diff options
author | David S. Miller <davem@davemloft.net> | 2009-03-26 18:23:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-26 18:23:24 -0400 |
commit | 08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6 (patch) | |
tree | 2be39bf8942edca1bcec735145e144a682ca9cd3 /drivers/usb/storage/shuttle_usbat.c | |
parent | f0de70f8bb56952f6e016a65a8a8d006918f5bf6 (diff) | |
parent | 0384e2959127a56d0640505d004d8dd92f9c29f5 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts:
drivers/net/wimax/i2400m/usb-notif.c
Diffstat (limited to 'drivers/usb/storage/shuttle_usbat.c')
-rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 202 |
1 files changed, 181 insertions, 21 deletions
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index ae6d64810d2a..b62a28814ebe 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -42,6 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
45 | #include <linux/module.h> | ||
45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
46 | #include <linux/cdrom.h> | 47 | #include <linux/cdrom.h> |
47 | 48 | ||
@@ -52,7 +53,100 @@ | |||
52 | #include "transport.h" | 53 | #include "transport.h" |
53 | #include "protocol.h" | 54 | #include "protocol.h" |
54 | #include "debug.h" | 55 | #include "debug.h" |
55 | #include "shuttle_usbat.h" | 56 | |
57 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); | ||
58 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
60 | |||
61 | /* Supported device types */ | ||
62 | #define USBAT_DEV_HP8200 0x01 | ||
63 | #define USBAT_DEV_FLASH 0x02 | ||
64 | |||
65 | #define USBAT_EPP_PORT 0x10 | ||
66 | #define USBAT_EPP_REGISTER 0x30 | ||
67 | #define USBAT_ATA 0x40 | ||
68 | #define USBAT_ISA 0x50 | ||
69 | |||
70 | /* Commands (need to be logically OR'd with an access type */ | ||
71 | #define USBAT_CMD_READ_REG 0x00 | ||
72 | #define USBAT_CMD_WRITE_REG 0x01 | ||
73 | #define USBAT_CMD_READ_BLOCK 0x02 | ||
74 | #define USBAT_CMD_WRITE_BLOCK 0x03 | ||
75 | #define USBAT_CMD_COND_READ_BLOCK 0x04 | ||
76 | #define USBAT_CMD_COND_WRITE_BLOCK 0x05 | ||
77 | #define USBAT_CMD_WRITE_REGS 0x07 | ||
78 | |||
79 | /* Commands (these don't need an access type) */ | ||
80 | #define USBAT_CMD_EXEC_CMD 0x80 | ||
81 | #define USBAT_CMD_SET_FEAT 0x81 | ||
82 | #define USBAT_CMD_UIO 0x82 | ||
83 | |||
84 | /* Methods of accessing UIO register */ | ||
85 | #define USBAT_UIO_READ 1 | ||
86 | #define USBAT_UIO_WRITE 0 | ||
87 | |||
88 | /* Qualifier bits */ | ||
89 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ | ||
90 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ | ||
91 | |||
92 | /* USBAT Flash Media status types */ | ||
93 | #define USBAT_FLASH_MEDIA_NONE 0 | ||
94 | #define USBAT_FLASH_MEDIA_CF 1 | ||
95 | |||
96 | /* USBAT Flash Media change types */ | ||
97 | #define USBAT_FLASH_MEDIA_SAME 0 | ||
98 | #define USBAT_FLASH_MEDIA_CHANGED 1 | ||
99 | |||
100 | /* USBAT ATA registers */ | ||
101 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ | ||
102 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ | ||
103 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ | ||
104 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ | ||
105 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ | ||
106 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ | ||
107 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ | ||
108 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ | ||
109 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ | ||
110 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ | ||
111 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ | ||
112 | |||
113 | /* USBAT User I/O Data registers */ | ||
114 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ | ||
115 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ | ||
116 | /* CDT = ACKD & !UI1 & !UI0 */ | ||
117 | #define USBAT_UIO_1 0x20 /* I/O 1 */ | ||
118 | #define USBAT_UIO_0 0x10 /* I/O 0 */ | ||
119 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ | ||
120 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ | ||
121 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ | ||
122 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ | ||
123 | |||
124 | /* USBAT User I/O Enable registers */ | ||
125 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ | ||
126 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ | ||
127 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ | ||
128 | /* If ACKD=1, set OE1 to 1 also. */ | ||
129 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ | ||
130 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ | ||
131 | |||
132 | /* USBAT Features */ | ||
133 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ | ||
134 | #define USBAT_FEAT_U1 0x08 | ||
135 | #define USBAT_FEAT_U0 0x04 | ||
136 | #define USBAT_FEAT_ET1 0x02 | ||
137 | #define USBAT_FEAT_ET2 0x01 | ||
138 | |||
139 | struct usbat_info { | ||
140 | int devicetype; | ||
141 | |||
142 | /* Used for Flash readers only */ | ||
143 | unsigned long sectors; /* total sector count */ | ||
144 | unsigned long ssize; /* sector size in bytes */ | ||
145 | |||
146 | unsigned char sense_key; | ||
147 | unsigned long sense_asc; /* additional sense code */ | ||
148 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
149 | }; | ||
56 | 150 | ||
57 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) | 151 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) |
58 | #define LSB_of(s) ((s)&0xFF) | 152 | #define LSB_of(s) ((s)&0xFF) |
@@ -63,6 +157,48 @@ static int transferred = 0; | |||
63 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); | 157 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); |
64 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); | 158 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); |
65 | 159 | ||
160 | static int init_usbat_cd(struct us_data *us); | ||
161 | static int init_usbat_flash(struct us_data *us); | ||
162 | |||
163 | |||
164 | /* | ||
165 | * The table of devices | ||
166 | */ | ||
167 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
168 | vendorName, productName, useProtocol, useTransport, \ | ||
169 | initFunction, flags) \ | ||
170 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
171 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
172 | |||
173 | struct usb_device_id usbat_usb_ids[] = { | ||
174 | # include "unusual_usbat.h" | ||
175 | { } /* Terminating entry */ | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(usb, usbat_usb_ids); | ||
178 | |||
179 | #undef UNUSUAL_DEV | ||
180 | |||
181 | /* | ||
182 | * The flags table | ||
183 | */ | ||
184 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
185 | vendor_name, product_name, use_protocol, use_transport, \ | ||
186 | init_function, Flags) \ | ||
187 | { \ | ||
188 | .vendorName = vendor_name, \ | ||
189 | .productName = product_name, \ | ||
190 | .useProtocol = use_protocol, \ | ||
191 | .useTransport = use_transport, \ | ||
192 | .initFunction = init_function, \ | ||
193 | } | ||
194 | |||
195 | static struct us_unusual_dev usbat_unusual_dev_list[] = { | ||
196 | # include "unusual_usbat.h" | ||
197 | { } /* Terminating entry */ | ||
198 | }; | ||
199 | |||
200 | #undef UNUSUAL_DEV | ||
201 | |||
66 | /* | 202 | /* |
67 | * Convenience function to produce an ATA read/write sectors command | 203 | * Convenience function to produce an ATA read/write sectors command |
68 | * Use cmd=0x20 for read, cmd=0x30 for write | 204 | * Use cmd=0x20 for read, cmd=0x30 for write |
@@ -1684,37 +1820,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
1684 | return USB_STOR_TRANSPORT_FAILED; | 1820 | return USB_STOR_TRANSPORT_FAILED; |
1685 | } | 1821 | } |
1686 | 1822 | ||
1687 | int init_usbat_cd(struct us_data *us) | 1823 | static int init_usbat_cd(struct us_data *us) |
1688 | { | 1824 | { |
1689 | return init_usbat(us, USBAT_DEV_HP8200); | 1825 | return init_usbat(us, USBAT_DEV_HP8200); |
1690 | } | 1826 | } |
1691 | 1827 | ||
1692 | 1828 | static int init_usbat_flash(struct us_data *us) | |
1693 | int init_usbat_flash(struct us_data *us) | ||
1694 | { | 1829 | { |
1695 | return init_usbat(us, USBAT_DEV_FLASH); | 1830 | return init_usbat(us, USBAT_DEV_FLASH); |
1696 | } | 1831 | } |
1697 | 1832 | ||
1698 | int init_usbat_probe(struct us_data *us) | 1833 | static int usbat_probe(struct usb_interface *intf, |
1834 | const struct usb_device_id *id) | ||
1699 | { | 1835 | { |
1700 | return init_usbat(us, 0); | 1836 | struct us_data *us; |
1837 | int result; | ||
1838 | |||
1839 | result = usb_stor_probe1(&us, intf, id, | ||
1840 | (id - usbat_usb_ids) + usbat_unusual_dev_list); | ||
1841 | if (result) | ||
1842 | return result; | ||
1843 | |||
1844 | /* The actual transport will be determined later by the | ||
1845 | * initialization routine; this is just a placeholder. | ||
1846 | */ | ||
1847 | us->transport_name = "Shuttle USBAT"; | ||
1848 | us->transport = usbat_flash_transport; | ||
1849 | us->transport_reset = usb_stor_CB_reset; | ||
1850 | us->max_lun = 1; | ||
1851 | |||
1852 | result = usb_stor_probe2(us); | ||
1853 | return result; | ||
1701 | } | 1854 | } |
1702 | 1855 | ||
1703 | /* | 1856 | static struct usb_driver usbat_driver = { |
1704 | * Default transport function. Attempts to detect which transport function | 1857 | .name = "ums-usbat", |
1705 | * should be called, makes it the new default, and calls it. | 1858 | .probe = usbat_probe, |
1706 | * | 1859 | .disconnect = usb_stor_disconnect, |
1707 | * This function should never be called. Our usbat_init() function detects the | 1860 | .suspend = usb_stor_suspend, |
1708 | * device type and changes the us->transport ptr to the transport function | 1861 | .resume = usb_stor_resume, |
1709 | * relevant to the device. | 1862 | .reset_resume = usb_stor_reset_resume, |
1710 | * However, we'll support this impossible(?) case anyway. | 1863 | .pre_reset = usb_stor_pre_reset, |
1711 | */ | 1864 | .post_reset = usb_stor_post_reset, |
1712 | int usbat_transport(struct scsi_cmnd *srb, struct us_data *us) | 1865 | .id_table = usbat_usb_ids, |
1866 | .soft_unbind = 1, | ||
1867 | }; | ||
1868 | |||
1869 | static int __init usbat_init(void) | ||
1713 | { | 1870 | { |
1714 | struct usbat_info *info = (struct usbat_info*) (us->extra); | 1871 | return usb_register(&usbat_driver); |
1715 | 1872 | } | |
1716 | if (usbat_set_transport(us, info, 0)) | ||
1717 | return USB_STOR_TRANSPORT_ERROR; | ||
1718 | 1873 | ||
1719 | return us->transport(srb, us); | 1874 | static void __exit usbat_exit(void) |
1875 | { | ||
1876 | usb_deregister(&usbat_driver); | ||
1720 | } | 1877 | } |
1878 | |||
1879 | module_init(usbat_init); | ||
1880 | module_exit(usbat_exit); | ||