aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2017-05-16 11:47:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-17 05:27:40 -0400
commit628c2893d44876ddd11602400c70606ade62e129 (patch)
tree7cd93437f41e713887fe43e2a1a4da4db68424af
parent9b31071dd18af2078cd866e39718f51f89b31c89 (diff)
USB: ene_usb6250: fix DMA to the stack
The ene_usb6250 sub-driver in usb-storage does USB I/O to buffers on the stack, which doesn't work with vmapped stacks. This patch fixes the problem by allocating a separate 512-byte buffer at probe time and using it for all of the offending I/O operations. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported-and-tested-by: Andreas Hartmann <andihartmann@01019freenet.de> CC: <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/storage/ene_ub6250.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index 369f3c24815a..44af719194b2 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -446,6 +446,10 @@ struct ms_lib_ctrl {
446#define SD_BLOCK_LEN 9 446#define SD_BLOCK_LEN 9
447 447
448struct ene_ub6250_info { 448struct ene_ub6250_info {
449
450 /* I/O bounce buffer */
451 u8 *bbuf;
452
449 /* for 6250 code */ 453 /* for 6250 code */
450 struct SD_STATUS SD_Status; 454 struct SD_STATUS SD_Status;
451 struct MS_STATUS MS_Status; 455 struct MS_STATUS MS_Status;
@@ -493,8 +497,11 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag);
493 497
494static void ene_ub6250_info_destructor(void *extra) 498static void ene_ub6250_info_destructor(void *extra)
495{ 499{
500 struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
501
496 if (!extra) 502 if (!extra)
497 return; 503 return;
504 kfree(info->bbuf);
498} 505}
499 506
500static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg) 507static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
@@ -860,8 +867,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
860 u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat) 867 u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
861{ 868{
862 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 869 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
870 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
871 u8 *bbuf = info->bbuf;
863 int result; 872 int result;
864 u8 ExtBuf[4];
865 u32 bn = PhyBlockAddr * 0x20 + PageNum; 873 u32 bn = PhyBlockAddr * 0x20 + PageNum;
866 874
867 result = ene_load_bincode(us, MS_RW_PATTERN); 875 result = ene_load_bincode(us, MS_RW_PATTERN);
@@ -901,7 +909,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
901 bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); 909 bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16);
902 bcb->CDB[6] = 0x01; 910 bcb->CDB[6] = 0x01;
903 911
904 result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); 912 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
905 if (result != USB_STOR_XFER_GOOD) 913 if (result != USB_STOR_XFER_GOOD)
906 return USB_STOR_TRANSPORT_ERROR; 914 return USB_STOR_TRANSPORT_ERROR;
907 915
@@ -910,9 +918,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
910 ExtraDat->status0 = 0x10; /* Not yet,fireware support */ 918 ExtraDat->status0 = 0x10; /* Not yet,fireware support */
911 919
912 ExtraDat->status1 = 0x00; /* Not yet,fireware support */ 920 ExtraDat->status1 = 0x00; /* Not yet,fireware support */
913 ExtraDat->ovrflg = ExtBuf[0]; 921 ExtraDat->ovrflg = bbuf[0];
914 ExtraDat->mngflg = ExtBuf[1]; 922 ExtraDat->mngflg = bbuf[1];
915 ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); 923 ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);
916 924
917 return USB_STOR_TRANSPORT_GOOD; 925 return USB_STOR_TRANSPORT_GOOD;
918} 926}
@@ -1332,8 +1340,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
1332 u8 PageNum, struct ms_lib_type_extdat *ExtraDat) 1340 u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
1333{ 1341{
1334 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 1342 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
1343 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1344 u8 *bbuf = info->bbuf;
1335 int result; 1345 int result;
1336 u8 ExtBuf[4];
1337 1346
1338 memset(bcb, 0, sizeof(struct bulk_cb_wrap)); 1347 memset(bcb, 0, sizeof(struct bulk_cb_wrap));
1339 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); 1348 bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -1347,7 +1356,7 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
1347 bcb->CDB[2] = (unsigned char)(PhyBlock>>16); 1356 bcb->CDB[2] = (unsigned char)(PhyBlock>>16);
1348 bcb->CDB[6] = 0x01; 1357 bcb->CDB[6] = 0x01;
1349 1358
1350 result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); 1359 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
1351 if (result != USB_STOR_XFER_GOOD) 1360 if (result != USB_STOR_XFER_GOOD)
1352 return USB_STOR_TRANSPORT_ERROR; 1361 return USB_STOR_TRANSPORT_ERROR;
1353 1362
@@ -1355,9 +1364,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
1355 ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */ 1364 ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */
1356 ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */ 1365 ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */
1357 ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */ 1366 ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */
1358 ExtraDat->ovrflg = ExtBuf[0]; 1367 ExtraDat->ovrflg = bbuf[0];
1359 ExtraDat->mngflg = ExtBuf[1]; 1368 ExtraDat->mngflg = bbuf[1];
1360 ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); 1369 ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);
1361 1370
1362 return USB_STOR_TRANSPORT_GOOD; 1371 return USB_STOR_TRANSPORT_GOOD;
1363} 1372}
@@ -1556,9 +1565,9 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
1556 u16 PhyBlock, newblk, i; 1565 u16 PhyBlock, newblk, i;
1557 u16 LogStart, LogEnde; 1566 u16 LogStart, LogEnde;
1558 struct ms_lib_type_extdat extdat; 1567 struct ms_lib_type_extdat extdat;
1559 u8 buf[0x200];
1560 u32 count = 0, index = 0; 1568 u32 count = 0, index = 0;
1561 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 1569 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
1570 u8 *bbuf = info->bbuf;
1562 1571
1563 for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) { 1572 for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
1564 ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde); 1573 ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
@@ -1572,14 +1581,16 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
1572 } 1581 }
1573 1582
1574 if (count == PhyBlock) { 1583 if (count == PhyBlock) {
1575 ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf); 1584 ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
1585 bbuf);
1576 count += 0x80; 1586 count += 0x80;
1577 } 1587 }
1578 index = (PhyBlock % 0x80) * 4; 1588 index = (PhyBlock % 0x80) * 4;
1579 1589
1580 extdat.ovrflg = buf[index]; 1590 extdat.ovrflg = bbuf[index];
1581 extdat.mngflg = buf[index+1]; 1591 extdat.mngflg = bbuf[index+1];
1582 extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]); 1592 extdat.logadr = memstick_logaddr(bbuf[index+2],
1593 bbuf[index+3]);
1583 1594
1584 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { 1595 if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
1585 ms_lib_setacquired_errorblock(us, PhyBlock); 1596 ms_lib_setacquired_errorblock(us, PhyBlock);
@@ -2062,9 +2073,9 @@ static int ene_ms_init(struct us_data *us)
2062{ 2073{
2063 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 2074 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
2064 int result; 2075 int result;
2065 u8 buf[0x200];
2066 u16 MSP_BlockSize, MSP_UserAreaBlocks; 2076 u16 MSP_BlockSize, MSP_UserAreaBlocks;
2067 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 2077 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
2078 u8 *bbuf = info->bbuf;
2068 2079
2069 printk(KERN_INFO "transport --- ENE_MSInit\n"); 2080 printk(KERN_INFO "transport --- ENE_MSInit\n");
2070 2081
@@ -2083,13 +2094,13 @@ static int ene_ms_init(struct us_data *us)
2083 bcb->CDB[0] = 0xF1; 2094 bcb->CDB[0] = 0xF1;
2084 bcb->CDB[1] = 0x01; 2095 bcb->CDB[1] = 0x01;
2085 2096
2086 result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); 2097 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
2087 if (result != USB_STOR_XFER_GOOD) { 2098 if (result != USB_STOR_XFER_GOOD) {
2088 printk(KERN_ERR "Execution MS Init Code Fail !!\n"); 2099 printk(KERN_ERR "Execution MS Init Code Fail !!\n");
2089 return USB_STOR_TRANSPORT_ERROR; 2100 return USB_STOR_TRANSPORT_ERROR;
2090 } 2101 }
2091 /* the same part to test ENE */ 2102 /* the same part to test ENE */
2092 info->MS_Status = *(struct MS_STATUS *)&buf[0]; 2103 info->MS_Status = *(struct MS_STATUS *) bbuf;
2093 2104
2094 if (info->MS_Status.Insert && info->MS_Status.Ready) { 2105 if (info->MS_Status.Insert && info->MS_Status.Ready) {
2095 printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); 2106 printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert);
@@ -2098,15 +2109,15 @@ static int ene_ms_init(struct us_data *us)
2098 printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); 2109 printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG);
2099 printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); 2110 printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
2100 if (info->MS_Status.IsMSPro) { 2111 if (info->MS_Status.IsMSPro) {
2101 MSP_BlockSize = (buf[6] << 8) | buf[7]; 2112 MSP_BlockSize = (bbuf[6] << 8) | bbuf[7];
2102 MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; 2113 MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
2103 info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; 2114 info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
2104 } else { 2115 } else {
2105 ms_card_init(us); /* Card is MS (to ms.c)*/ 2116 ms_card_init(us); /* Card is MS (to ms.c)*/
2106 } 2117 }
2107 usb_stor_dbg(us, "MS Init Code OK !!\n"); 2118 usb_stor_dbg(us, "MS Init Code OK !!\n");
2108 } else { 2119 } else {
2109 usb_stor_dbg(us, "MS Card Not Ready --- %x\n", buf[0]); 2120 usb_stor_dbg(us, "MS Card Not Ready --- %x\n", bbuf[0]);
2110 return USB_STOR_TRANSPORT_ERROR; 2121 return USB_STOR_TRANSPORT_ERROR;
2111 } 2122 }
2112 2123
@@ -2116,9 +2127,9 @@ static int ene_ms_init(struct us_data *us)
2116static int ene_sd_init(struct us_data *us) 2127static int ene_sd_init(struct us_data *us)
2117{ 2128{
2118 int result; 2129 int result;
2119 u8 buf[0x200];
2120 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; 2130 struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
2121 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; 2131 struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
2132 u8 *bbuf = info->bbuf;
2122 2133
2123 usb_stor_dbg(us, "transport --- ENE_SDInit\n"); 2134 usb_stor_dbg(us, "transport --- ENE_SDInit\n");
2124 /* SD Init Part-1 */ 2135 /* SD Init Part-1 */
@@ -2152,17 +2163,17 @@ static int ene_sd_init(struct us_data *us)
2152 bcb->Flags = US_BULK_FLAG_IN; 2163 bcb->Flags = US_BULK_FLAG_IN;
2153 bcb->CDB[0] = 0xF1; 2164 bcb->CDB[0] = 0xF1;
2154 2165
2155 result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); 2166 result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
2156 if (result != USB_STOR_XFER_GOOD) { 2167 if (result != USB_STOR_XFER_GOOD) {
2157 usb_stor_dbg(us, "Execution SD Init Code Fail !!\n"); 2168 usb_stor_dbg(us, "Execution SD Init Code Fail !!\n");
2158 return USB_STOR_TRANSPORT_ERROR; 2169 return USB_STOR_TRANSPORT_ERROR;
2159 } 2170 }
2160 2171
2161 info->SD_Status = *(struct SD_STATUS *)&buf[0]; 2172 info->SD_Status = *(struct SD_STATUS *) bbuf;
2162 if (info->SD_Status.Insert && info->SD_Status.Ready) { 2173 if (info->SD_Status.Insert && info->SD_Status.Ready) {
2163 struct SD_STATUS *s = &info->SD_Status; 2174 struct SD_STATUS *s = &info->SD_Status;
2164 2175
2165 ene_get_card_status(us, (unsigned char *)&buf); 2176 ene_get_card_status(us, bbuf);
2166 usb_stor_dbg(us, "Insert = %x\n", s->Insert); 2177 usb_stor_dbg(us, "Insert = %x\n", s->Insert);
2167 usb_stor_dbg(us, "Ready = %x\n", s->Ready); 2178 usb_stor_dbg(us, "Ready = %x\n", s->Ready);
2168 usb_stor_dbg(us, "IsMMC = %x\n", s->IsMMC); 2179 usb_stor_dbg(us, "IsMMC = %x\n", s->IsMMC);
@@ -2170,7 +2181,7 @@ static int ene_sd_init(struct us_data *us)
2170 usb_stor_dbg(us, "HiSpeed = %x\n", s->HiSpeed); 2181 usb_stor_dbg(us, "HiSpeed = %x\n", s->HiSpeed);
2171 usb_stor_dbg(us, "WtP = %x\n", s->WtP); 2182 usb_stor_dbg(us, "WtP = %x\n", s->WtP);
2172 } else { 2183 } else {
2173 usb_stor_dbg(us, "SD Card Not Ready --- %x\n", buf[0]); 2184 usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]);
2174 return USB_STOR_TRANSPORT_ERROR; 2185 return USB_STOR_TRANSPORT_ERROR;
2175 } 2186 }
2176 return USB_STOR_TRANSPORT_GOOD; 2187 return USB_STOR_TRANSPORT_GOOD;
@@ -2180,13 +2191,15 @@ static int ene_sd_init(struct us_data *us)
2180static int ene_init(struct us_data *us) 2191static int ene_init(struct us_data *us)
2181{ 2192{
2182 int result; 2193 int result;
2183 u8 misc_reg03 = 0; 2194 u8 misc_reg03;
2184 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); 2195 struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
2196 u8 *bbuf = info->bbuf;
2185 2197
2186 result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); 2198 result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
2187 if (result != USB_STOR_XFER_GOOD) 2199 if (result != USB_STOR_XFER_GOOD)
2188 return USB_STOR_TRANSPORT_ERROR; 2200 return USB_STOR_TRANSPORT_ERROR;
2189 2201
2202 misc_reg03 = bbuf[0];
2190 if (misc_reg03 & 0x01) { 2203 if (misc_reg03 & 0x01) {
2191 if (!info->SD_Status.Ready) { 2204 if (!info->SD_Status.Ready) {
2192 result = ene_sd_init(us); 2205 result = ene_sd_init(us);
@@ -2303,8 +2316,9 @@ static int ene_ub6250_probe(struct usb_interface *intf,
2303 const struct usb_device_id *id) 2316 const struct usb_device_id *id)
2304{ 2317{
2305 int result; 2318 int result;
2306 u8 misc_reg03 = 0; 2319 u8 misc_reg03;
2307 struct us_data *us; 2320 struct us_data *us;
2321 struct ene_ub6250_info *info;
2308 2322
2309 result = usb_stor_probe1(&us, intf, id, 2323 result = usb_stor_probe1(&us, intf, id,
2310 (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list, 2324 (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list,
@@ -2313,11 +2327,16 @@ static int ene_ub6250_probe(struct usb_interface *intf,
2313 return result; 2327 return result;
2314 2328
2315 /* FIXME: where should the code alloc extra buf ? */ 2329 /* FIXME: where should the code alloc extra buf ? */
2316 if (!us->extra) { 2330 us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
2317 us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL); 2331 if (!us->extra)
2318 if (!us->extra) 2332 return -ENOMEM;
2319 return -ENOMEM; 2333 us->extra_destructor = ene_ub6250_info_destructor;
2320 us->extra_destructor = ene_ub6250_info_destructor; 2334
2335 info = (struct ene_ub6250_info *)(us->extra);
2336 info->bbuf = kmalloc(512, GFP_KERNEL);
2337 if (!info->bbuf) {
2338 kfree(us->extra);
2339 return -ENOMEM;
2321 } 2340 }
2322 2341
2323 us->transport_name = "ene_ub6250"; 2342 us->transport_name = "ene_ub6250";
@@ -2329,12 +2348,13 @@ static int ene_ub6250_probe(struct usb_interface *intf,
2329 return result; 2348 return result;
2330 2349
2331 /* probe card type */ 2350 /* probe card type */
2332 result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03); 2351 result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
2333 if (result != USB_STOR_XFER_GOOD) { 2352 if (result != USB_STOR_XFER_GOOD) {
2334 usb_stor_disconnect(intf); 2353 usb_stor_disconnect(intf);
2335 return USB_STOR_TRANSPORT_ERROR; 2354 return USB_STOR_TRANSPORT_ERROR;
2336 } 2355 }
2337 2356
2357 misc_reg03 = info->bbuf[0];
2338 if (!(misc_reg03 & 0x01)) { 2358 if (!(misc_reg03 & 0x01)) {
2339 pr_info("ums_eneub6250: This driver only supports SD/MS cards. " 2359 pr_info("ums_eneub6250: This driver only supports SD/MS cards. "
2340 "It does not support SM cards.\n"); 2360 "It does not support SM cards.\n");