aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/alauda.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-02-12 14:48:22 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:35 -0400
commita74bba3bf92cb6425789ae5050bdcca1283bc6f4 (patch)
tree780c54b99a7df31f94d074b8eab3383d3452ba6c /drivers/usb/storage/alauda.c
parenta9fb6d05d59c9e118ad8c355adfdf88c970c61bc (diff)
usb-storage: make alauda a separate module
This patch (as1215) converts usb-storage's alauda subdriver into a separate module. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/storage/alauda.c')
-rw-r--r--drivers/usb/storage/alauda.c163
1 files changed, 160 insertions, 3 deletions
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 5407411e30e0..d3a88ebe690b 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -31,6 +31,8 @@
31 * 675 Mass Ave, Cambridge, MA 02139, USA. 31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */ 32 */
33 33
34#include <linux/module.h>
35
34#include <scsi/scsi.h> 36#include <scsi/scsi.h>
35#include <scsi/scsi_cmnd.h> 37#include <scsi/scsi_cmnd.h>
36#include <scsi/scsi_device.h> 38#include <scsi/scsi_device.h>
@@ -39,7 +41,75 @@
39#include "transport.h" 41#include "transport.h"
40#include "protocol.h" 42#include "protocol.h"
41#include "debug.h" 43#include "debug.h"
42#include "alauda.h" 44
45/*
46 * Status bytes
47 */
48#define ALAUDA_STATUS_ERROR 0x01
49#define ALAUDA_STATUS_READY 0x40
50
51/*
52 * Control opcodes (for request field)
53 */
54#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
55#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
56#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
57#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
58#define ALAUDA_GET_XD_MEDIA_SIG 0x86
59#define ALAUDA_GET_SM_MEDIA_SIG 0x96
60
61/*
62 * Bulk command identity (byte 0)
63 */
64#define ALAUDA_BULK_CMD 0x40
65
66/*
67 * Bulk opcodes (byte 1)
68 */
69#define ALAUDA_BULK_GET_REDU_DATA 0x85
70#define ALAUDA_BULK_READ_BLOCK 0x94
71#define ALAUDA_BULK_ERASE_BLOCK 0xa3
72#define ALAUDA_BULK_WRITE_BLOCK 0xb4
73#define ALAUDA_BULK_GET_STATUS2 0xb7
74#define ALAUDA_BULK_RESET_MEDIA 0xe0
75
76/*
77 * Port to operate on (byte 8)
78 */
79#define ALAUDA_PORT_XD 0x00
80#define ALAUDA_PORT_SM 0x01
81
82/*
83 * LBA and PBA are unsigned ints. Special values.
84 */
85#define UNDEF 0xffff
86#define SPARE 0xfffe
87#define UNUSABLE 0xfffd
88
89struct alauda_media_info {
90 unsigned long capacity; /* total media size in bytes */
91 unsigned int pagesize; /* page size in bytes */
92 unsigned int blocksize; /* number of pages per block */
93 unsigned int uzonesize; /* number of usable blocks per zone */
94 unsigned int zonesize; /* number of blocks per zone */
95 unsigned int blockmask; /* mask to get page from address */
96
97 unsigned char pageshift;
98 unsigned char blockshift;
99 unsigned char zoneshift;
100
101 u16 **lba_to_pba; /* logical to physical block map */
102 u16 **pba_to_lba; /* physical to logical block map */
103};
104
105struct alauda_info {
106 struct alauda_media_info port[2];
107 int wr_ep; /* endpoint to write data out of */
108
109 unsigned char sense_key;
110 unsigned long sense_asc; /* additional sense code */
111 unsigned long sense_ascq; /* additional sense code qualifier */
112};
43 113
44#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) 114#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
45#define LSB_of(s) ((s)&0xFF) 115#define LSB_of(s) ((s)&0xFF)
@@ -52,6 +122,48 @@
52#define PBA_HI(pba) (pba >> 3) 122#define PBA_HI(pba) (pba >> 3)
53#define PBA_ZONE(pba) (pba >> 11) 123#define PBA_ZONE(pba) (pba >> 11)
54 124
125static int init_alauda(struct us_data *us);
126
127
128/*
129 * The table of devices
130 */
131#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
132 vendorName, productName, useProtocol, useTransport, \
133 initFunction, flags) \
134{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
135 .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
136
137struct usb_device_id alauda_usb_ids[] = {
138# include "unusual_alauda.h"
139 { } /* Terminating entry */
140};
141MODULE_DEVICE_TABLE(usb, alauda_usb_ids);
142
143#undef UNUSUAL_DEV
144
145/*
146 * The flags table
147 */
148#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
149 vendor_name, product_name, use_protocol, use_transport, \
150 init_function, Flags) \
151{ \
152 .vendorName = vendor_name, \
153 .productName = product_name, \
154 .useProtocol = use_protocol, \
155 .useTransport = use_transport, \
156 .initFunction = init_function, \
157}
158
159static struct us_unusual_dev alauda_unusual_dev_list[] = {
160# include "unusual_alauda.h"
161 { } /* Terminating entry */
162};
163
164#undef UNUSUAL_DEV
165
166
55/* 167/*
56 * Media handling 168 * Media handling
57 */ 169 */
@@ -998,7 +1110,7 @@ static void alauda_info_destructor(void *extra)
998/* 1110/*
999 * Initialize alauda_info struct and find the data-write endpoint 1111 * Initialize alauda_info struct and find the data-write endpoint
1000 */ 1112 */
1001int init_alauda(struct us_data *us) 1113static int init_alauda(struct us_data *us)
1002{ 1114{
1003 struct alauda_info *info; 1115 struct alauda_info *info;
1004 struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; 1116 struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
@@ -1020,7 +1132,7 @@ int init_alauda(struct us_data *us)
1020 return USB_STOR_TRANSPORT_GOOD; 1132 return USB_STOR_TRANSPORT_GOOD;
1021} 1133}
1022 1134
1023int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) 1135static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
1024{ 1136{
1025 int rc; 1137 int rc;
1026 struct alauda_info *info = (struct alauda_info *) us->extra; 1138 struct alauda_info *info = (struct alauda_info *) us->extra;
@@ -1128,3 +1240,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
1128 return USB_STOR_TRANSPORT_FAILED; 1240 return USB_STOR_TRANSPORT_FAILED;
1129} 1241}
1130 1242
1243static int alauda_probe(struct usb_interface *intf,
1244 const struct usb_device_id *id)
1245{
1246 struct us_data *us;
1247 int result;
1248
1249 result = usb_stor_probe1(&us, intf, id,
1250 (id - alauda_usb_ids) + alauda_unusual_dev_list);
1251 if (result)
1252 return result;
1253
1254 us->transport_name = "Alauda Control/Bulk";
1255 us->transport = alauda_transport;
1256 us->transport_reset = usb_stor_Bulk_reset;
1257 us->max_lun = 1;
1258
1259 result = usb_stor_probe2(us);
1260 return result;
1261}
1262
1263static struct usb_driver alauda_driver = {
1264 .name = "ums-alauda",
1265 .probe = alauda_probe,
1266 .disconnect = usb_stor_disconnect,
1267 .suspend = usb_stor_suspend,
1268 .resume = usb_stor_resume,
1269 .reset_resume = usb_stor_reset_resume,
1270 .pre_reset = usb_stor_pre_reset,
1271 .post_reset = usb_stor_post_reset,
1272 .id_table = alauda_usb_ids,
1273 .soft_unbind = 1,
1274};
1275
1276static int __init alauda_init(void)
1277{
1278 return usb_register(&alauda_driver);
1279}
1280
1281static void __exit alauda_exit(void)
1282{
1283 usb_deregister(&alauda_driver);
1284}
1285
1286module_init(alauda_init);
1287module_exit(alauda_exit);