aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/alauda.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage/alauda.c')
-rw-r--r--drivers/usb/storage/alauda.c192
1 files changed, 180 insertions, 12 deletions
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 8d3711a7ff06..67edc65acb8e 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,79 @@
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
45MODULE_DESCRIPTION("Driver for Alauda-based card readers");
46MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
47MODULE_LICENSE("GPL");
48
49/*
50 * Status bytes
51 */
52#define ALAUDA_STATUS_ERROR 0x01
53#define ALAUDA_STATUS_READY 0x40
54
55/*
56 * Control opcodes (for request field)
57 */
58#define ALAUDA_GET_XD_MEDIA_STATUS 0x08
59#define ALAUDA_GET_SM_MEDIA_STATUS 0x98
60#define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a
61#define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a
62#define ALAUDA_GET_XD_MEDIA_SIG 0x86
63#define ALAUDA_GET_SM_MEDIA_SIG 0x96
64
65/*
66 * Bulk command identity (byte 0)
67 */
68#define ALAUDA_BULK_CMD 0x40
69
70/*
71 * Bulk opcodes (byte 1)
72 */
73#define ALAUDA_BULK_GET_REDU_DATA 0x85
74#define ALAUDA_BULK_READ_BLOCK 0x94
75#define ALAUDA_BULK_ERASE_BLOCK 0xa3
76#define ALAUDA_BULK_WRITE_BLOCK 0xb4
77#define ALAUDA_BULK_GET_STATUS2 0xb7
78#define ALAUDA_BULK_RESET_MEDIA 0xe0
79
80/*
81 * Port to operate on (byte 8)
82 */
83#define ALAUDA_PORT_XD 0x00
84#define ALAUDA_PORT_SM 0x01
85
86/*
87 * LBA and PBA are unsigned ints. Special values.
88 */
89#define UNDEF 0xffff
90#define SPARE 0xfffe
91#define UNUSABLE 0xfffd
92
93struct alauda_media_info {
94 unsigned long capacity; /* total media size in bytes */
95 unsigned int pagesize; /* page size in bytes */
96 unsigned int blocksize; /* number of pages per block */
97 unsigned int uzonesize; /* number of usable blocks per zone */
98 unsigned int zonesize; /* number of blocks per zone */
99 unsigned int blockmask; /* mask to get page from address */
100
101 unsigned char pageshift;
102 unsigned char blockshift;
103 unsigned char zoneshift;
104
105 u16 **lba_to_pba; /* logical to physical block map */
106 u16 **pba_to_lba; /* physical to logical block map */
107};
108
109struct alauda_info {
110 struct alauda_media_info port[2];
111 int wr_ep; /* endpoint to write data out of */
112
113 unsigned char sense_key;
114 unsigned long sense_asc; /* additional sense code */
115 unsigned long sense_ascq; /* additional sense code qualifier */
116};
43 117
44#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) 118#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
45#define LSB_of(s) ((s)&0xFF) 119#define LSB_of(s) ((s)&0xFF)
@@ -52,6 +126,48 @@
52#define PBA_HI(pba) (pba >> 3) 126#define PBA_HI(pba) (pba >> 3)
53#define PBA_ZONE(pba) (pba >> 11) 127#define PBA_ZONE(pba) (pba >> 11)
54 128
129static int init_alauda(struct us_data *us);
130
131
132/*
133 * The table of devices
134 */
135#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
136 vendorName, productName, useProtocol, useTransport, \
137 initFunction, flags) \
138{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \
139 .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
140
141struct usb_device_id alauda_usb_ids[] = {
142# include "unusual_alauda.h"
143 { } /* Terminating entry */
144};
145MODULE_DEVICE_TABLE(usb, alauda_usb_ids);
146
147#undef UNUSUAL_DEV
148
149/*
150 * The flags table
151 */
152#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
153 vendor_name, product_name, use_protocol, use_transport, \
154 init_function, Flags) \
155{ \
156 .vendorName = vendor_name, \
157 .productName = product_name, \
158 .useProtocol = use_protocol, \
159 .useTransport = use_transport, \
160 .initFunction = init_function, \
161}
162
163static struct us_unusual_dev alauda_unusual_dev_list[] = {
164# include "unusual_alauda.h"
165 { } /* Terminating entry */
166};
167
168#undef UNUSUAL_DEV
169
170
55/* 171/*
56 * Media handling 172 * Media handling
57 */ 173 */
@@ -307,7 +423,8 @@ static int alauda_init_media(struct us_data *us)
307 data[0], data[1], data[2], data[3]); 423 data[0], data[1], data[2], data[3]);
308 media_info = alauda_card_find_id(data[1]); 424 media_info = alauda_card_find_id(data[1]);
309 if (media_info == NULL) { 425 if (media_info == NULL) {
310 printk("alauda_init_media: Unrecognised media signature: " 426 printk(KERN_WARNING
427 "alauda_init_media: Unrecognised media signature: "
311 "%02X %02X %02X %02X\n", 428 "%02X %02X %02X %02X\n",
312 data[0], data[1], data[2], data[3]); 429 data[0], data[1], data[2], data[3]);
313 return USB_STOR_TRANSPORT_ERROR; 430 return USB_STOR_TRANSPORT_ERROR;
@@ -518,7 +635,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
518 635
519 /* check even parity */ 636 /* check even parity */
520 if (parity[data[6] ^ data[7]]) { 637 if (parity[data[6] ^ data[7]]) {
521 printk("alauda_read_map: Bad parity in LBA for block %d" 638 printk(KERN_WARNING
639 "alauda_read_map: Bad parity in LBA for block %d"
522 " (%02X %02X)\n", i, data[6], data[7]); 640 " (%02X %02X)\n", i, data[6], data[7]);
523 pba_to_lba[i] = UNUSABLE; 641 pba_to_lba[i] = UNUSABLE;
524 continue; 642 continue;
@@ -538,13 +656,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone)
538 */ 656 */
539 657
540 if (lba_offset >= uzonesize) { 658 if (lba_offset >= uzonesize) {
541 printk("alauda_read_map: Bad low LBA %d for block %d\n", 659 printk(KERN_WARNING
660 "alauda_read_map: Bad low LBA %d for block %d\n",
542 lba_real, blocknum); 661 lba_real, blocknum);
543 continue; 662 continue;
544 } 663 }
545 664
546 if (lba_to_pba[lba_offset] != UNDEF) { 665 if (lba_to_pba[lba_offset] != UNDEF) {
547 printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", 666 printk(KERN_WARNING
667 "alauda_read_map: "
668 "LBA %d seen for PBA %d and %d\n",
548 lba_real, lba_to_pba[lba_offset], blocknum); 669 lba_real, lba_to_pba[lba_offset], blocknum);
549 continue; 670 continue;
550 } 671 }
@@ -712,13 +833,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba,
712 if (pba == 1) { 833 if (pba == 1) {
713 /* Maybe it is impossible to write to PBA 1. 834 /* Maybe it is impossible to write to PBA 1.
714 Fake success, but don't do anything. */ 835 Fake success, but don't do anything. */
715 printk("alauda_write_lba: avoid writing to pba 1\n"); 836 printk(KERN_WARNING
837 "alauda_write_lba: avoid writing to pba 1\n");
716 return USB_STOR_TRANSPORT_GOOD; 838 return USB_STOR_TRANSPORT_GOOD;
717 } 839 }
718 840
719 new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); 841 new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
720 if (!new_pba) { 842 if (!new_pba) {
721 printk("alauda_write_lba: Out of unused blocks\n"); 843 printk(KERN_WARNING
844 "alauda_write_lba: Out of unused blocks\n");
722 return USB_STOR_TRANSPORT_ERROR; 845 return USB_STOR_TRANSPORT_ERROR;
723 } 846 }
724 847
@@ -818,7 +941,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
818 len = min(sectors, blocksize) * (pagesize + 64); 941 len = min(sectors, blocksize) * (pagesize + 64);
819 buffer = kmalloc(len, GFP_NOIO); 942 buffer = kmalloc(len, GFP_NOIO);
820 if (buffer == NULL) { 943 if (buffer == NULL) {
821 printk("alauda_read_data: Out of memory\n"); 944 printk(KERN_WARNING "alauda_read_data: Out of memory\n");
822 return USB_STOR_TRANSPORT_ERROR; 945 return USB_STOR_TRANSPORT_ERROR;
823 } 946 }
824 947
@@ -911,7 +1034,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
911 len = min(sectors, blocksize) * pagesize; 1034 len = min(sectors, blocksize) * pagesize;
912 buffer = kmalloc(len, GFP_NOIO); 1035 buffer = kmalloc(len, GFP_NOIO);
913 if (buffer == NULL) { 1036 if (buffer == NULL) {
914 printk("alauda_write_data: Out of memory\n"); 1037 printk(KERN_WARNING "alauda_write_data: Out of memory\n");
915 return USB_STOR_TRANSPORT_ERROR; 1038 return USB_STOR_TRANSPORT_ERROR;
916 } 1039 }
917 1040
@@ -921,7 +1044,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
921 */ 1044 */
922 blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); 1045 blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
923 if (blockbuffer == NULL) { 1046 if (blockbuffer == NULL) {
924 printk("alauda_write_data: Out of memory\n"); 1047 printk(KERN_WARNING "alauda_write_data: Out of memory\n");
925 kfree(buffer); 1048 kfree(buffer);
926 return USB_STOR_TRANSPORT_ERROR; 1049 return USB_STOR_TRANSPORT_ERROR;
927 } 1050 }
@@ -991,7 +1114,7 @@ static void alauda_info_destructor(void *extra)
991/* 1114/*
992 * Initialize alauda_info struct and find the data-write endpoint 1115 * Initialize alauda_info struct and find the data-write endpoint
993 */ 1116 */
994int init_alauda(struct us_data *us) 1117static int init_alauda(struct us_data *us)
995{ 1118{
996 struct alauda_info *info; 1119 struct alauda_info *info;
997 struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; 1120 struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
@@ -1013,7 +1136,7 @@ int init_alauda(struct us_data *us)
1013 return USB_STOR_TRANSPORT_GOOD; 1136 return USB_STOR_TRANSPORT_GOOD;
1014} 1137}
1015 1138
1016int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) 1139static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
1017{ 1140{
1018 int rc; 1141 int rc;
1019 struct alauda_info *info = (struct alauda_info *) us->extra; 1142 struct alauda_info *info = (struct alauda_info *) us->extra;
@@ -1121,3 +1244,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
1121 return USB_STOR_TRANSPORT_FAILED; 1244 return USB_STOR_TRANSPORT_FAILED;
1122} 1245}
1123 1246
1247static int alauda_probe(struct usb_interface *intf,
1248 const struct usb_device_id *id)
1249{
1250 struct us_data *us;
1251 int result;
1252
1253 result = usb_stor_probe1(&us, intf, id,
1254 (id - alauda_usb_ids) + alauda_unusual_dev_list);
1255 if (result)
1256 return result;
1257
1258 us->transport_name = "Alauda Control/Bulk";
1259 us->transport = alauda_transport;
1260 us->transport_reset = usb_stor_Bulk_reset;
1261 us->max_lun = 1;
1262
1263 result = usb_stor_probe2(us);
1264 return result;
1265}
1266
1267static struct usb_driver alauda_driver = {
1268 .name = "ums-alauda",
1269 .probe = alauda_probe,
1270 .disconnect = usb_stor_disconnect,
1271 .suspend = usb_stor_suspend,
1272 .resume = usb_stor_resume,
1273 .reset_resume = usb_stor_reset_resume,
1274 .pre_reset = usb_stor_pre_reset,
1275 .post_reset = usb_stor_post_reset,
1276 .id_table = alauda_usb_ids,
1277 .soft_unbind = 1,
1278};
1279
1280static int __init alauda_init(void)
1281{
1282 return usb_register(&alauda_driver);
1283}
1284
1285static void __exit alauda_exit(void)
1286{
1287 usb_deregister(&alauda_driver);
1288}
1289
1290module_init(alauda_init);
1291module_exit(alauda_exit);