OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
13 KiB

  1. # --- T2-COPYRIGHT-NOTE-BEGIN ---
  2. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  3. #
  4. # T2 SDE: package/.../linux26mm/adaptec-usbxchange.patch
  5. # Copyright (C) 2006 The T2 SDE Project
  6. #
  7. # More information can be found in the files COPYING and README.
  8. #
  9. # This patch file is dual-licensed. It is available under the license the
  10. # patched project is licensed under, as long as it is an OpenSource license
  11. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  12. # of the GNU General Public License as published by the Free Software
  13. # Foundation; either version 2 of the License, or (at your option) any later
  14. # version.
  15. # --- T2-COPYRIGHT-NOTE-END ---
  16. Support for the Adaptec USB*Xchange family of USB<->SCSI cables.
  17. - Rene Rebe <rene@exactcode.de>
  18. --- linux-2.6.15-mm4/drivers/usb/storage/Kconfig 2006-01-30 12:16:10.838447250 +0100
  19. +++ linux-2.6.15-usb2x/drivers/usb/storage/Kconfig 2006-01-30 12:09:28.857325000 +0100
  20. @@ -134,6 +134,13 @@
  21. this input in any keybinding software. (e.g. gnome's keyboard short-
  22. cuts)
  23. +config USB_USBXCHANGE
  24. + tristate "Adaptec USBXchange and USB2Xchange firmware loader"
  25. + depends on USB_STORAGE
  26. + help
  27. + Say Y here to include additional code to load the firmware into the
  28. + Adaptec USBXchange and USB2Xchange USB --> SCSI converter dongle.
  29. +
  30. config USB_LIBUSUAL
  31. bool "The shared table of common (or usual) storage devices"
  32. depends on USB
  33. --- linux-2.6.15-mm4/drivers/usb/storage/Makefile 2006-01-30 12:16:10.838447250 +0100
  34. +++ linux-2.6.15-usb2x/drivers/usb/storage/Makefile 2006-01-30 12:08:29.781633000 +0100
  35. @@ -24,6 +24,8 @@
  36. usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
  37. initializers.o $(usb-storage-obj-y)
  38. +obj-$(CONFIG_USB_USBXCHANGE) += usbxchange_fw.o
  39. +
  40. ifneq ($(CONFIG_USB_LIBUSUAL),)
  41. obj-$(CONFIG_USB) += libusual.o
  42. endif
  43. --- linux-2.6.15-mm4/drivers/usb/storage/initializers.c 2006-01-30 12:16:10.826446500 +0100
  44. +++ linux-2.6.15-usb2x/drivers/usb/storage/initializers.c 2006-01-30 12:08:09.340355500 +0100
  45. @@ -164,3 +164,27 @@
  46. return USB_STOR_TRANSPORT_FAILED;
  47. }
  48. +/* Firmware Initialisation for the Adaptec USB2Xchange, needed for
  49. + * to recognize devices properly. Ren� Rebe <rene@exactcode.de> */
  50. +int usb2xchange_init(struct us_data *us)
  51. +{
  52. + int result;
  53. +
  54. + US_DEBUGP ("usb2xchange_init: initialising after reenumeration.\n");
  55. +
  56. + result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe,
  57. + 0x5a, 0x40, 0x01,
  58. + 0, 0, // buffer,
  59. + 0, // length,
  60. + 300);
  61. + US_DEBUGP ("usb2xchange_init: reset #1 (%d)\n", result);
  62. +
  63. + result = usb_control_msg(us->pusb_dev, us->send_ctrl_pipe,
  64. + 0x5a, 0x40, 0x02,
  65. + 0, 0, // buffer,
  66. + 0, // length,
  67. + 300);
  68. + US_DEBUGP ("usb2xchange_init: reset #2 (%d)\n", result);
  69. +
  70. + return result;
  71. +}
  72. --- linux-2.6.15-mm4/drivers/usb/storage/initializers.h 2006-01-30 12:16:10.826446500 +0100
  73. +++ linux-2.6.15-usb2x/drivers/usb/storage/initializers.h 2006-01-30 12:04:35.110967000 +0100
  74. @@ -49,3 +49,6 @@
  75. * flash reader */
  76. int usb_stor_ucr61s2b_init(struct us_data *us);
  77. int rio_karma_init(struct us_data *us);
  78. +
  79. +/* Firmware Initialization for the Adaptec USB2Xchange */
  80. +int usb2xchange_init(struct us_data *us);
  81. --- linux-2.6.15-mm4/drivers/usb/storage/unusual_devs.h 2006-01-30 12:16:10.870449250 +0100
  82. +++ linux-2.6.15-usb2x/drivers/usb/storage/unusual_devs.h 2006-01-27 21:49:46.570867000 +0100
  83. @@ -1180,6 +1180,21 @@
  84. US_FL_SINGLE_LUN),
  85. #endif
  86. +/* Adaptec USBXchange and USB2Xchange, after firmware download.
  87. + * Requires Ez-USB Style firmware loader. Ren� Rebe <rene@exactcode.de> */
  88. +
  89. +UNUSUAL_DEV( 0x03f3, 0x2001, 0x0000, 0xffff,
  90. + "Adaptec",
  91. + "USBXchange",
  92. + US_SC_SCSI, US_PR_BULK, NULL,
  93. + 0 ),
  94. +
  95. +UNUSUAL_DEV( 0x03f3, 0x2003, 0x0000, 0xffff,
  96. + "Adaptec",
  97. + "USB2Xchange",
  98. + US_SC_SCSI, US_PR_BULK, usb2xchange_init,
  99. + US_FL_SCM_MULT_TARG ),
  100. +
  101. /* Control/Bulk transport for all SubClass values */
  102. USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
  103. USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
  104. --- linux-2.6.15-mm4/drivers/usb/storage/usbxchange_fw.c 1970-01-01 01:00:00.000000000 +0100
  105. +++ linux-2.6.15-usb2x/drivers/usb/storage/usbxchange_fw.c 2006-01-28 09:45:14.308438000 +0100
  106. @@ -0,0 +1,215 @@
  107. +/*
  108. + * Firmware loader for Adaptec USBXchange / USB2Xchange.
  109. + *
  110. + * Uploads device firmware into the Adaptec USBXchange and USB2Xchange
  111. + * USB --> SCSI dongle.
  112. + *
  113. + * Current development and maintenance by:
  114. + * (c) 2005 Ren� Rebe <rene@exactcode.de>
  115. + *
  116. + * Initial work by:
  117. + * (c) 2004 Beier & Dauskardt IT <sda@bdit.de>
  118. + *
  119. + * Based on emi26.c:
  120. + * (c) 2002 Tapio Laxstr�m <tapio.laxstrom@iptime.fi>
  121. + *
  122. + * To use this driver, you need to get the devices firmware from some
  123. + * windows driver:
  124. + * usbxchg_win_v120.exe - for USBXchange
  125. + * usb2xchg_win_drv_v200.exe - for USB2Xchange
  126. + *
  127. + * Hotplug firmware loader compatible files can be found at:
  128. + * http://dl.exactcode.de/adaptec-usbxchange/
  129. + *
  130. + * Note:
  131. + * The USB2Xchange seems to have some internal buffer < 64K.
  132. + * Sending 64K requests crashes the device. Possibly it needs a
  133. + * "max_sectors: 8" setting.
  134. + *
  135. + * This program is distributed in the hope that it will be useful, but
  136. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  137. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  138. + * General Public License for more details.
  139. + *
  140. + * This program is free software; you can redistribute it and/or modify
  141. + * it under the terms of the GNU General Public License, as published by
  142. + * the Free Software Foundation, version 2.
  143. + */
  144. +
  145. +#include <linux/kernel.h>
  146. +#include <linux/errno.h>
  147. +#include <linux/slab.h>
  148. +#include <linux/module.h>
  149. +#include <linux/init.h>
  150. +#include <linux/usb.h>
  151. +#include <linux/firmware.h>
  152. +
  153. +#include "usbxchange_fw.h"
  154. +
  155. +static int usbxchange_writememory(struct usb_device *dev, int address,
  156. + unsigned char *data, int length,
  157. + __u8 bRequest);
  158. +static int usbxchange_set_reset(struct usb_device *dev, int cpureg,
  159. + unsigned char reset_bit);
  160. +static int usbxchange_load_firmware(struct usb_device *dev);
  161. +
  162. +static int usbxchange_probe(struct usb_interface *iface,
  163. + const struct usb_device_id *id);
  164. +static void usbxchange_disconnect(struct usb_interface *iface);
  165. +static int __init usbxchange_init(void);
  166. +static void __exit usbxchange_exit(void);
  167. +
  168. +#define usbxchange_VENDOR_ID 0x03f3
  169. +#define usbxchange_PRODUCT_ID 0x2000
  170. +#define usb2xchange_PRODUCT_ID 0x2002
  171. +
  172. +static struct usb_device_id usbxchange_usb_ids[] = {
  173. + {USB_DEVICE(usbxchange_VENDOR_ID, usbxchange_PRODUCT_ID)},
  174. + {USB_DEVICE(usbxchange_VENDOR_ID, usb2xchange_PRODUCT_ID)},
  175. + {} /* terminating entry */
  176. +};
  177. +
  178. +MODULE_DEVICE_TABLE(usb, usbxchange_usb_ids);
  179. +
  180. +/* thanks to drivers/usb/serial/keyspan_pda.c code */
  181. +static int usbxchange_writememory(struct usb_device *dev, int address,
  182. + unsigned char *data, int length, __u8 request)
  183. +{
  184. + int result;
  185. + unsigned char *buffer = kmalloc(length, GFP_KERNEL);
  186. +
  187. + if (!buffer) {
  188. + printk(KERN_ERR "usbxchange: kmalloc(%d) failed.\n", length);
  189. + return -ENOMEM;
  190. + }
  191. + memcpy(buffer, data, length);
  192. + result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, 0x40,
  193. + address, 0, buffer, length, 300);
  194. + kfree(buffer);
  195. + return result;
  196. +}
  197. +
  198. +/* thanks to drivers/usb/serial/keyspan_pda.c code */
  199. +static int usbxchange_set_reset(struct usb_device *dev, int cpureg,
  200. + unsigned char reset_bit)
  201. +{
  202. + int response;
  203. + printk(KERN_INFO "%s - %d\n", __FUNCTION__, reset_bit);
  204. + response =
  205. + usbxchange_writememory(dev, cpureg, &reset_bit, 1,
  206. + ANCHOR_LOAD_INTERNAL);
  207. + if (response < 0) {
  208. + printk(KERN_ERR "usbxchange: set_reset (%d) failed\n",
  209. + reset_bit);
  210. + }
  211. + return response;
  212. +}
  213. +
  214. +static int usbxchange_load_firmware(struct usb_device *dev)
  215. +{
  216. + INTEL_HEX_RECORD *record;
  217. + int err, cpureg;
  218. +
  219. + const struct firmware *firmware;
  220. +
  221. + switch (le16_to_cpu(dev->descriptor.idProduct)) {
  222. + case usbxchange_PRODUCT_ID:
  223. + err = request_firmware(&firmware, "usbxchange.fw", &dev->dev);
  224. + cpureg = CPUCS_REG;
  225. + break;
  226. + case usb2xchange_PRODUCT_ID:
  227. + err = request_firmware(&firmware, "usb2xchange.fw", &dev->dev);
  228. + cpureg = CPUCS_REG_FX2;
  229. + break;
  230. + default:
  231. + printk(KERN_ERR "%s - device not recognized %x\n", __FUNCTION__,
  232. + le16_to_cpu(dev->descriptor.idProduct));
  233. + return 1;
  234. + }
  235. +
  236. + if (err != 0) {
  237. + printk(KERN_ERR "Hotplug firmware request failed.\n");
  238. + return err;
  239. + }
  240. +
  241. + /* Stop CPU */
  242. + err = usbxchange_set_reset(dev, cpureg, 1);
  243. + err = usbxchange_set_reset(dev, cpureg, 1);
  244. + if (err < 0) {
  245. + printk(KERN_ERR "%s - error stopping dongle CPU: error = %d\n",
  246. + __FUNCTION__, err);
  247. + return err;
  248. + }
  249. +
  250. + /* Upload firmware */
  251. + for (record = (INTEL_HEX_RECORD *)firmware->data;
  252. + record->type == 0; record++) {
  253. +
  254. + err = usbxchange_writememory(dev, le32_to_cpu(record->address),
  255. + record->data,
  256. + le32_to_cpu(record->length),
  257. + ANCHOR_LOAD_INTERNAL);
  258. + if (err < 0) {
  259. + printk(KERN_ERR
  260. + "%s - error loading firmware: error = %d\n",
  261. + __FUNCTION__, err);
  262. + return err;
  263. + }
  264. + }
  265. +
  266. + /* De-assert reset (let the CPU run) */
  267. + err = usbxchange_set_reset(dev, cpureg, 1);
  268. + err = usbxchange_set_reset(dev, cpureg, 0);
  269. + if (err < 0) {
  270. + printk(KERN_ERR "%s - error resetting dongle CPU: error = %d\n",
  271. + __FUNCTION__, err);
  272. + return err;
  273. + }
  274. +
  275. + return 0;
  276. +}
  277. +
  278. +static int usbxchange_probe(struct usb_interface *iface,
  279. + const struct usb_device_id *id)
  280. +{
  281. + struct usb_device *dev = interface_to_usbdev(iface);
  282. +
  283. + printk(KERN_INFO "%s start\n", __FUNCTION__);
  284. +
  285. + usbxchange_load_firmware(dev);
  286. +
  287. + /* forcing an unload would save some kB of kernel memory ... */
  288. + return 0;
  289. +}
  290. +
  291. +static void usbxchange_disconnect(struct usb_interface *iface)
  292. +{
  293. +}
  294. +
  295. +static struct usb_driver usbxchange_driver = {
  296. + .name = "usbxchange_fw",
  297. + .probe = usbxchange_probe,
  298. + .disconnect = usbxchange_disconnect,
  299. + .id_table = usbxchange_usb_ids,
  300. +};
  301. +
  302. +static int __init usbxchange_init(void)
  303. +{
  304. + usb_register(&usbxchange_driver);
  305. + return 0;
  306. +}
  307. +
  308. +static void __exit usbxchange_exit(void)
  309. +{
  310. + usb_deregister(&usbxchange_driver);
  311. +}
  312. +
  313. +module_init(usbxchange_init);
  314. +module_exit(usbxchange_exit);
  315. +
  316. +MODULE_AUTHOR("Ren� Rebe <rene@exactcode.de>, Sancho Dauskardt <sda@bdit.de>");
  317. +MODULE_DESCRIPTION("Adaptec USBXchange firmware loader.");
  318. +MODULE_LICENSE("GPL");
  319. +
  320. +/* vi:ai:syntax=c:sw=8:ts=8:tw=80
  321. + */
  322. --- linux-2.6.15-mm4/drivers/usb/storage/usbxchange_fw.h 1970-01-01 01:00:00.000000000 +0100
  323. +++ linux-2.6.15-usb2x/drivers/usb/storage/usbxchange_fw.h 2006-01-27 17:18:18.246377000 +0100
  324. @@ -0,0 +1,45 @@
  325. +/*
  326. + * Firmware loader for Adaptec USBXchange / USB2Xchange.
  327. + *
  328. + * Uploads device firmware into the Adaptec USBXchange and USB2Xchange
  329. + * USB --> SCSI dongle.
  330. + *
  331. + * Current development and maintenance by:
  332. + * (c) 2005 Ren� Rebe <rene@exactcode.de>
  333. + *
  334. + * Initial work by:
  335. + * (c) 2004 Beier & Dauskardt IT <sda@bdit.de>
  336. + *
  337. + * Based on emi26.c:
  338. + * (c) 2002 Tapio Laxstr�m <tapio.laxstrom@iptime.fi>
  339. + *
  340. + * This program is distributed in the hope that it will be useful, but
  341. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  342. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  343. + * General Public License for more details.
  344. + *
  345. + * This program is free software; you can redistribute it and/or modify
  346. + * it under the terms of the GNU General Public License, as published by
  347. + * the Free Software Foundation, version 2.
  348. + */
  349. +
  350. +#ifndef _USB_USBXCHANGE_FW_H_INCLUDED
  351. +#define _USB_USBXCHANGE_FW_H_INCLUDED
  352. +
  353. +#define MAX_INTEL_HEX_RECORD_LENGTH 16
  354. +typedef struct _INTEL_HEX_RECORD {
  355. + __u32 length;
  356. + __u32 address;
  357. + __u32 type;
  358. + __u8 data[MAX_INTEL_HEX_RECORD_LENGTH];
  359. +} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
  360. +
  361. +/* Vendor specific request code for Anchor Upload/Download
  362. + (This one is implemented in the core). */
  363. +#define ANCHOR_LOAD_INTERNAL 0xA0
  364. +
  365. +/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
  366. +#define CPUCS_REG 0x7F92 /* original / FX */
  367. +#define CPUCS_REG_FX2 0xE600 /* FX2 */
  368. +
  369. +#endif
  370. --- linux-2.6.15/drivers/usb/storage/transport.c 2006-01-03 04:21:10.000000000 +0100
  371. +++ ./drivers/usb/storage/transport.c 2006-01-30 19:41:26.727402000 +0100
  372. @@ -984,6 +984,11 @@
  373. bcb->Lun = srb->device->lun;
  374. if (us->flags & US_FL_SCM_MULT_TARG)
  375. bcb->Lun |= srb->device->id << 4;
  376. + /* Adaptec USB2Xchange */
  377. + if (us->pusb_dev->descriptor.idVendor == 0x03f3 &&
  378. + us->pusb_dev->descriptor.idProduct == 0x2003)
  379. + bcb->Lun = srb->device->id;
  380. +
  381. bcb->Length = srb->cmd_len;
  382. /* copy the command payload */
  383. @@ -1069,6 +1074,20 @@
  384. US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
  385. le32_to_cpu(bcs->Signature), bcs->Tag,
  386. residue, bcs->Status);
  387. + if (bcs->Status > US_BULK_STAT_FAIL) {
  388. + /* Adaptec USB2XCHANGE ? */
  389. + if (us->pusb_dev->descriptor.idVendor == 0x03f3 &&
  390. + us->pusb_dev->descriptor.idProduct == 0x2003) {
  391. +
  392. + /* This device will send
  393. + * bcs->Status == 0x8a for unused LUN's
  394. + * bcs->Status == 0x02 for SRB's that require SENSE.
  395. + */
  396. + bcs->Status = US_BULK_STAT_OK;
  397. + fake_sense = 1;
  398. + US_DEBUGP("Patched Bulk status to %d.\n", bcs->Status);
  399. + }
  400. + }
  401. if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) {
  402. US_DEBUGP("Bulk logical error\n");
  403. return USB_STOR_TRANSPORT_ERROR;