diff options
Diffstat (limited to 'drivers/usb/storage/sddr09.c')
-rw-r--r-- | drivers/usb/storage/sddr09.c | 147 |
1 files changed, 127 insertions, 20 deletions
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 531ae5c5abf..ab5f9f37575 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -41,6 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | 42 | ||
43 | #include <linux/errno.h> | 43 | #include <linux/errno.h> |
44 | #include <linux/module.h> | ||
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | 46 | ||
46 | #include <scsi/scsi.h> | 47 | #include <scsi/scsi.h> |
@@ -51,7 +52,53 @@ | |||
51 | #include "transport.h" | 52 | #include "transport.h" |
52 | #include "protocol.h" | 53 | #include "protocol.h" |
53 | #include "debug.h" | 54 | #include "debug.h" |
54 | #include "sddr09.h" | 55 | |
56 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); | ||
57 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); | ||
58 | MODULE_LICENSE("GPL"); | ||
59 | |||
60 | static int usb_stor_sddr09_dpcm_init(struct us_data *us); | ||
61 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
62 | static int usb_stor_sddr09_init(struct us_data *us); | ||
63 | |||
64 | |||
65 | /* | ||
66 | * The table of devices | ||
67 | */ | ||
68 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
69 | vendorName, productName, useProtocol, useTransport, \ | ||
70 | initFunction, flags) \ | ||
71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
73 | |||
74 | struct usb_device_id sddr09_usb_ids[] = { | ||
75 | # include "unusual_sddr09.h" | ||
76 | { } /* Terminating entry */ | ||
77 | }; | ||
78 | MODULE_DEVICE_TABLE(usb, sddr09_usb_ids); | ||
79 | |||
80 | #undef UNUSUAL_DEV | ||
81 | |||
82 | /* | ||
83 | * The flags table | ||
84 | */ | ||
85 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
86 | vendor_name, product_name, use_protocol, use_transport, \ | ||
87 | init_function, Flags) \ | ||
88 | { \ | ||
89 | .vendorName = vendor_name, \ | ||
90 | .productName = product_name, \ | ||
91 | .useProtocol = use_protocol, \ | ||
92 | .useTransport = use_transport, \ | ||
93 | .initFunction = init_function, \ | ||
94 | } | ||
95 | |||
96 | static struct us_unusual_dev sddr09_unusual_dev_list[] = { | ||
97 | # include "unusual_sddr09.h" | ||
98 | { } /* Terminating entry */ | ||
99 | }; | ||
100 | |||
101 | #undef UNUSUAL_DEV | ||
55 | 102 | ||
56 | 103 | ||
57 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 104 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
@@ -723,7 +770,7 @@ sddr09_read_data(struct us_data *us, | |||
723 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 770 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
724 | buffer = kmalloc(len, GFP_NOIO); | 771 | buffer = kmalloc(len, GFP_NOIO); |
725 | if (buffer == NULL) { | 772 | if (buffer == NULL) { |
726 | printk("sddr09_read_data: Out of memory\n"); | 773 | printk(KERN_WARNING "sddr09_read_data: Out of memory\n"); |
727 | return -ENOMEM; | 774 | return -ENOMEM; |
728 | } | 775 | } |
729 | 776 | ||
@@ -838,7 +885,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
838 | if (pba == UNDEF) { | 885 | if (pba == UNDEF) { |
839 | pba = sddr09_find_unused_pba(info, lba); | 886 | pba = sddr09_find_unused_pba(info, lba); |
840 | if (!pba) { | 887 | if (!pba) { |
841 | printk("sddr09_write_lba: Out of unused blocks\n"); | 888 | printk(KERN_WARNING |
889 | "sddr09_write_lba: Out of unused blocks\n"); | ||
842 | return -ENOSPC; | 890 | return -ENOSPC; |
843 | } | 891 | } |
844 | info->pba_to_lba[pba] = lba; | 892 | info->pba_to_lba[pba] = lba; |
@@ -849,7 +897,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
849 | if (pba == 1) { | 897 | if (pba == 1) { |
850 | /* Maybe it is impossible to write to PBA 1. | 898 | /* Maybe it is impossible to write to PBA 1. |
851 | Fake success, but don't do anything. */ | 899 | Fake success, but don't do anything. */ |
852 | printk("sddr09: avoid writing to pba 1\n"); | 900 | printk(KERN_WARNING "sddr09: avoid writing to pba 1\n"); |
853 | return 0; | 901 | return 0; |
854 | } | 902 | } |
855 | 903 | ||
@@ -954,7 +1002,7 @@ sddr09_write_data(struct us_data *us, | |||
954 | blocklen = (pagelen << info->blockshift); | 1002 | blocklen = (pagelen << info->blockshift); |
955 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 1003 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
956 | if (!blockbuffer) { | 1004 | if (!blockbuffer) { |
957 | printk("sddr09_write_data: Out of memory\n"); | 1005 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
958 | return -ENOMEM; | 1006 | return -ENOMEM; |
959 | } | 1007 | } |
960 | 1008 | ||
@@ -965,7 +1013,7 @@ sddr09_write_data(struct us_data *us, | |||
965 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 1013 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
966 | buffer = kmalloc(len, GFP_NOIO); | 1014 | buffer = kmalloc(len, GFP_NOIO); |
967 | if (buffer == NULL) { | 1015 | if (buffer == NULL) { |
968 | printk("sddr09_write_data: Out of memory\n"); | 1016 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
969 | kfree(blockbuffer); | 1017 | kfree(blockbuffer); |
970 | return -ENOMEM; | 1018 | return -ENOMEM; |
971 | } | 1019 | } |
@@ -1112,7 +1160,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1112 | 1160 | ||
1113 | if (result) { | 1161 | if (result) { |
1114 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1162 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
1115 | printk("sddr09: could not read card info\n"); | 1163 | printk(KERN_WARNING "sddr09: could not read card info\n"); |
1116 | return NULL; | 1164 | return NULL; |
1117 | } | 1165 | } |
1118 | 1166 | ||
@@ -1153,7 +1201,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
1153 | sprintf(blurbtxt + strlen(blurbtxt), | 1201 | sprintf(blurbtxt + strlen(blurbtxt), |
1154 | ", WP"); | 1202 | ", WP"); |
1155 | 1203 | ||
1156 | printk("%s\n", blurbtxt); | 1204 | printk(KERN_WARNING "%s\n", blurbtxt); |
1157 | 1205 | ||
1158 | return cardinfo; | 1206 | return cardinfo; |
1159 | } | 1207 | } |
@@ -1184,7 +1232,7 @@ sddr09_read_map(struct us_data *us) { | |||
1184 | alloc_len = (alloc_blocks << CONTROL_SHIFT); | 1232 | alloc_len = (alloc_blocks << CONTROL_SHIFT); |
1185 | buffer = kmalloc(alloc_len, GFP_NOIO); | 1233 | buffer = kmalloc(alloc_len, GFP_NOIO); |
1186 | if (buffer == NULL) { | 1234 | if (buffer == NULL) { |
1187 | printk("sddr09_read_map: out of memory\n"); | 1235 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
1188 | result = -1; | 1236 | result = -1; |
1189 | goto done; | 1237 | goto done; |
1190 | } | 1238 | } |
@@ -1198,7 +1246,7 @@ sddr09_read_map(struct us_data *us) { | |||
1198 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); | 1246 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); |
1199 | 1247 | ||
1200 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { | 1248 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { |
1201 | printk("sddr09_read_map: out of memory\n"); | 1249 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
1202 | result = -1; | 1250 | result = -1; |
1203 | goto done; | 1251 | goto done; |
1204 | } | 1252 | } |
@@ -1238,7 +1286,8 @@ sddr09_read_map(struct us_data *us) { | |||
1238 | if (ptr[j] != 0) | 1286 | if (ptr[j] != 0) |
1239 | goto nonz; | 1287 | goto nonz; |
1240 | info->pba_to_lba[i] = UNUSABLE; | 1288 | info->pba_to_lba[i] = UNUSABLE; |
1241 | printk("sddr09: PBA %d has no logical mapping\n", i); | 1289 | printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n", |
1290 | i); | ||
1242 | continue; | 1291 | continue; |
1243 | 1292 | ||
1244 | nonz: | 1293 | nonz: |
@@ -1251,7 +1300,8 @@ sddr09_read_map(struct us_data *us) { | |||
1251 | nonff: | 1300 | nonff: |
1252 | /* normal PBAs start with six FFs */ | 1301 | /* normal PBAs start with six FFs */ |
1253 | if (j < 6) { | 1302 | if (j < 6) { |
1254 | printk("sddr09: PBA %d has no logical mapping: " | 1303 | printk(KERN_WARNING |
1304 | "sddr09: PBA %d has no logical mapping: " | ||
1255 | "reserved area = %02X%02X%02X%02X " | 1305 | "reserved area = %02X%02X%02X%02X " |
1256 | "data status %02X block status %02X\n", | 1306 | "data status %02X block status %02X\n", |
1257 | i, ptr[0], ptr[1], ptr[2], ptr[3], | 1307 | i, ptr[0], ptr[1], ptr[2], ptr[3], |
@@ -1261,7 +1311,8 @@ sddr09_read_map(struct us_data *us) { | |||
1261 | } | 1311 | } |
1262 | 1312 | ||
1263 | if ((ptr[6] >> 4) != 0x01) { | 1313 | if ((ptr[6] >> 4) != 0x01) { |
1264 | printk("sddr09: PBA %d has invalid address field " | 1314 | printk(KERN_WARNING |
1315 | "sddr09: PBA %d has invalid address field " | ||
1265 | "%02X%02X/%02X%02X\n", | 1316 | "%02X%02X/%02X%02X\n", |
1266 | i, ptr[6], ptr[7], ptr[11], ptr[12]); | 1317 | i, ptr[6], ptr[7], ptr[11], ptr[12]); |
1267 | info->pba_to_lba[i] = UNUSABLE; | 1318 | info->pba_to_lba[i] = UNUSABLE; |
@@ -1270,7 +1321,8 @@ sddr09_read_map(struct us_data *us) { | |||
1270 | 1321 | ||
1271 | /* check even parity */ | 1322 | /* check even parity */ |
1272 | if (parity[ptr[6] ^ ptr[7]]) { | 1323 | if (parity[ptr[6] ^ ptr[7]]) { |
1273 | printk("sddr09: Bad parity in LBA for block %d" | 1324 | printk(KERN_WARNING |
1325 | "sddr09: Bad parity in LBA for block %d" | ||
1274 | " (%02X %02X)\n", i, ptr[6], ptr[7]); | 1326 | " (%02X %02X)\n", i, ptr[6], ptr[7]); |
1275 | info->pba_to_lba[i] = UNUSABLE; | 1327 | info->pba_to_lba[i] = UNUSABLE; |
1276 | continue; | 1328 | continue; |
@@ -1289,7 +1341,8 @@ sddr09_read_map(struct us_data *us) { | |||
1289 | */ | 1341 | */ |
1290 | 1342 | ||
1291 | if (lba >= 1000) { | 1343 | if (lba >= 1000) { |
1292 | printk("sddr09: Bad low LBA %d for block %d\n", | 1344 | printk(KERN_WARNING |
1345 | "sddr09: Bad low LBA %d for block %d\n", | ||
1293 | lba, i); | 1346 | lba, i); |
1294 | goto possibly_erase; | 1347 | goto possibly_erase; |
1295 | } | 1348 | } |
@@ -1297,7 +1350,8 @@ sddr09_read_map(struct us_data *us) { | |||
1297 | lba += 1000*(i/0x400); | 1350 | lba += 1000*(i/0x400); |
1298 | 1351 | ||
1299 | if (info->lba_to_pba[lba] != UNDEF) { | 1352 | if (info->lba_to_pba[lba] != UNDEF) { |
1300 | printk("sddr09: LBA %d seen for PBA %d and %d\n", | 1353 | printk(KERN_WARNING |
1354 | "sddr09: LBA %d seen for PBA %d and %d\n", | ||
1301 | lba, info->lba_to_pba[lba], i); | 1355 | lba, info->lba_to_pba[lba], i); |
1302 | goto possibly_erase; | 1356 | goto possibly_erase; |
1303 | } | 1357 | } |
@@ -1399,7 +1453,7 @@ sddr09_common_init(struct us_data *us) { | |||
1399 | * unusual devices list but called from here then LUN 0 of the combo reader | 1453 | * unusual devices list but called from here then LUN 0 of the combo reader |
1400 | * is not recognized. But I do not know what precisely these calls do. | 1454 | * is not recognized. But I do not know what precisely these calls do. |
1401 | */ | 1455 | */ |
1402 | int | 1456 | static int |
1403 | usb_stor_sddr09_dpcm_init(struct us_data *us) { | 1457 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
1404 | int result; | 1458 | int result; |
1405 | unsigned char *data = us->iobuf; | 1459 | unsigned char *data = us->iobuf; |
@@ -1449,7 +1503,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) { | |||
1449 | /* | 1503 | /* |
1450 | * Transport for the Microtech DPCM-USB | 1504 | * Transport for the Microtech DPCM-USB |
1451 | */ | 1505 | */ |
1452 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | 1506 | static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) |
1453 | { | 1507 | { |
1454 | int ret; | 1508 | int ret; |
1455 | 1509 | ||
@@ -1491,7 +1545,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1491 | /* | 1545 | /* |
1492 | * Transport for the Sandisk SDDR-09 | 1546 | * Transport for the Sandisk SDDR-09 |
1493 | */ | 1547 | */ |
1494 | int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | 1548 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) |
1495 | { | 1549 | { |
1496 | static unsigned char sensekey = 0, sensecode = 0; | 1550 | static unsigned char sensekey = 0, sensecode = 0; |
1497 | static unsigned char havefakesense = 0; | 1551 | static unsigned char havefakesense = 0; |
@@ -1690,7 +1744,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1690 | /* | 1744 | /* |
1691 | * Initialization routine for the sddr09 subdriver | 1745 | * Initialization routine for the sddr09 subdriver |
1692 | */ | 1746 | */ |
1693 | int | 1747 | static int |
1694 | usb_stor_sddr09_init(struct us_data *us) { | 1748 | usb_stor_sddr09_init(struct us_data *us) { |
1695 | return sddr09_common_init(us); | 1749 | return sddr09_common_init(us); |
1696 | } | 1750 | } |
1751 | |||
1752 | static int sddr09_probe(struct usb_interface *intf, | ||
1753 | const struct usb_device_id *id) | ||
1754 | { | ||
1755 | struct us_data *us; | ||
1756 | int result; | ||
1757 | |||
1758 | result = usb_stor_probe1(&us, intf, id, | ||
1759 | (id - sddr09_usb_ids) + sddr09_unusual_dev_list); | ||
1760 | if (result) | ||
1761 | return result; | ||
1762 | |||
1763 | if (us->protocol == US_PR_DPCM_USB) { | ||
1764 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
1765 | us->transport = dpcm_transport; | ||
1766 | us->transport_reset = usb_stor_CB_reset; | ||
1767 | us->max_lun = 1; | ||
1768 | } else { | ||
1769 | us->transport_name = "EUSB/SDDR09"; | ||
1770 | us->transport = sddr09_transport; | ||
1771 | us->transport_reset = usb_stor_CB_reset; | ||
1772 | us->max_lun = 0; | ||
1773 | } | ||
1774 | |||
1775 | result = usb_stor_probe2(us); | ||
1776 | return result; | ||
1777 | } | ||
1778 | |||
1779 | static struct usb_driver sddr09_driver = { | ||
1780 | .name = "ums-sddr09", | ||
1781 | .probe = sddr09_probe, | ||
1782 | .disconnect = usb_stor_disconnect, | ||
1783 | .suspend = usb_stor_suspend, | ||
1784 | .resume = usb_stor_resume, | ||
1785 | .reset_resume = usb_stor_reset_resume, | ||
1786 | .pre_reset = usb_stor_pre_reset, | ||
1787 | .post_reset = usb_stor_post_reset, | ||
1788 | .id_table = sddr09_usb_ids, | ||
1789 | .soft_unbind = 1, | ||
1790 | }; | ||
1791 | |||
1792 | static int __init sddr09_init(void) | ||
1793 | { | ||
1794 | return usb_register(&sddr09_driver); | ||
1795 | } | ||
1796 | |||
1797 | static void __exit sddr09_exit(void) | ||
1798 | { | ||
1799 | usb_deregister(&sddr09_driver); | ||
1800 | } | ||
1801 | |||
1802 | module_init(sddr09_init); | ||
1803 | module_exit(sddr09_exit); | ||