aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/isd200.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage/isd200.c')
-rw-r--r--drivers/usb/storage/isd200.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 49ba6c0ff1e8..178e8c2a8a2f 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -49,6 +49,7 @@
49#include <linux/slab.h> 49#include <linux/slab.h>
50#include <linux/hdreg.h> 50#include <linux/hdreg.h>
51#include <linux/ide.h> 51#include <linux/ide.h>
52#include <linux/scatterlist.h>
52 53
53#include <scsi/scsi.h> 54#include <scsi/scsi.h>
54#include <scsi/scsi_cmnd.h> 55#include <scsi/scsi_cmnd.h>
@@ -287,6 +288,7 @@ struct isd200_info {
287 /* maximum number of LUNs supported */ 288 /* maximum number of LUNs supported */
288 unsigned char MaxLUNs; 289 unsigned char MaxLUNs;
289 struct scsi_cmnd srb; 290 struct scsi_cmnd srb;
291 struct scatterlist sg;
290}; 292};
291 293
292 294
@@ -398,6 +400,31 @@ static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb)
398 * Transport routines 400 * Transport routines
399 ***********************************************************************/ 401 ***********************************************************************/
400 402
403/**************************************************************************
404 * isd200_set_srb(), isd200_srb_set_bufflen()
405 *
406 * Two helpers to facilitate in initialization of scsi_cmnd structure
407 * Will need to change when struct scsi_cmnd changes
408 */
409static void isd200_set_srb(struct isd200_info *info,
410 enum dma_data_direction dir, void* buff, unsigned bufflen)
411{
412 struct scsi_cmnd *srb = &info->srb;
413
414 if (buff)
415 sg_init_one(&info->sg, buff, bufflen);
416
417 srb->sc_data_direction = dir;
418 srb->request_buffer = buff ? &info->sg : NULL;
419 srb->request_bufflen = bufflen;
420 srb->use_sg = buff ? 1 : 0;
421}
422
423static void isd200_srb_set_bufflen(struct scsi_cmnd *srb, unsigned bufflen)
424{
425 srb->request_bufflen = bufflen;
426}
427
401 428
402/************************************************************************** 429/**************************************************************************
403 * isd200_action 430 * isd200_action
@@ -432,9 +459,7 @@ static int isd200_action( struct us_data *us, int action,
432 ata.generic.RegisterSelect = 459 ata.generic.RegisterSelect =
433 REG_CYLINDER_LOW | REG_CYLINDER_HIGH | 460 REG_CYLINDER_LOW | REG_CYLINDER_HIGH |
434 REG_STATUS | REG_ERROR; 461 REG_STATUS | REG_ERROR;
435 srb->sc_data_direction = DMA_FROM_DEVICE; 462 isd200_set_srb(info, DMA_FROM_DEVICE, pointer, value);
436 srb->request_buffer = pointer;
437 srb->request_bufflen = value;
438 break; 463 break;
439 464
440 case ACTION_ENUM: 465 case ACTION_ENUM:
@@ -444,7 +469,7 @@ static int isd200_action( struct us_data *us, int action,
444 ACTION_SELECT_5; 469 ACTION_SELECT_5;
445 ata.generic.RegisterSelect = REG_DEVICE_HEAD; 470 ata.generic.RegisterSelect = REG_DEVICE_HEAD;
446 ata.write.DeviceHeadByte = value; 471 ata.write.DeviceHeadByte = value;
447 srb->sc_data_direction = DMA_NONE; 472 isd200_set_srb(info, DMA_NONE, NULL, 0);
448 break; 473 break;
449 474
450 case ACTION_RESET: 475 case ACTION_RESET:
@@ -453,7 +478,7 @@ static int isd200_action( struct us_data *us, int action,
453 ACTION_SELECT_3|ACTION_SELECT_4; 478 ACTION_SELECT_3|ACTION_SELECT_4;
454 ata.generic.RegisterSelect = REG_DEVICE_CONTROL; 479 ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
455 ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER; 480 ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER;
456 srb->sc_data_direction = DMA_NONE; 481 isd200_set_srb(info, DMA_NONE, NULL, 0);
457 break; 482 break;
458 483
459 case ACTION_REENABLE: 484 case ACTION_REENABLE:
@@ -462,7 +487,7 @@ static int isd200_action( struct us_data *us, int action,
462 ACTION_SELECT_3|ACTION_SELECT_4; 487 ACTION_SELECT_3|ACTION_SELECT_4;
463 ata.generic.RegisterSelect = REG_DEVICE_CONTROL; 488 ata.generic.RegisterSelect = REG_DEVICE_CONTROL;
464 ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER; 489 ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER;
465 srb->sc_data_direction = DMA_NONE; 490 isd200_set_srb(info, DMA_NONE, NULL, 0);
466 break; 491 break;
467 492
468 case ACTION_SOFT_RESET: 493 case ACTION_SOFT_RESET:
@@ -471,21 +496,20 @@ static int isd200_action( struct us_data *us, int action,
471 ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND; 496 ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
472 ata.write.DeviceHeadByte = info->DeviceHead; 497 ata.write.DeviceHeadByte = info->DeviceHead;
473 ata.write.CommandByte = WIN_SRST; 498 ata.write.CommandByte = WIN_SRST;
474 srb->sc_data_direction = DMA_NONE; 499 isd200_set_srb(info, DMA_NONE, NULL, 0);
475 break; 500 break;
476 501
477 case ACTION_IDENTIFY: 502 case ACTION_IDENTIFY:
478 US_DEBUGP(" isd200_action(IDENTIFY)\n"); 503 US_DEBUGP(" isd200_action(IDENTIFY)\n");
479 ata.generic.RegisterSelect = REG_COMMAND; 504 ata.generic.RegisterSelect = REG_COMMAND;
480 ata.write.CommandByte = WIN_IDENTIFY; 505 ata.write.CommandByte = WIN_IDENTIFY;
481 srb->sc_data_direction = DMA_FROM_DEVICE; 506 isd200_set_srb(info, DMA_FROM_DEVICE, info->id,
482 srb->request_buffer = (void *) info->id; 507 sizeof(struct hd_driveid));
483 srb->request_bufflen = sizeof(struct hd_driveid);
484 break; 508 break;
485 509
486 default: 510 default:
487 US_DEBUGP("Error: Undefined action %d\n",action); 511 US_DEBUGP("Error: Undefined action %d\n",action);
488 break; 512 return ISD200_ERROR;
489 } 513 }
490 514
491 memcpy(srb->cmnd, &ata, sizeof(ata.generic)); 515 memcpy(srb->cmnd, &ata, sizeof(ata.generic));
@@ -590,7 +614,7 @@ static void isd200_invoke_transport( struct us_data *us,
590 return; 614 return;
591 } 615 }
592 616
593 if ((srb->resid > 0) && 617 if ((scsi_get_resid(srb) > 0) &&
594 !((srb->cmnd[0] == REQUEST_SENSE) || 618 !((srb->cmnd[0] == REQUEST_SENSE) ||
595 (srb->cmnd[0] == INQUIRY) || 619 (srb->cmnd[0] == INQUIRY) ||
596 (srb->cmnd[0] == MODE_SENSE) || 620 (srb->cmnd[0] == MODE_SENSE) ||
@@ -1217,7 +1241,6 @@ static int isd200_get_inquiry_data( struct us_data *us )
1217 return(retStatus); 1241 return(retStatus);
1218} 1242}
1219 1243
1220
1221/************************************************************************** 1244/**************************************************************************
1222 * isd200_scsi_to_ata 1245 * isd200_scsi_to_ata
1223 * 1246 *
@@ -1266,7 +1289,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
1266 ataCdb->generic.TransferBlockSize = 1; 1289 ataCdb->generic.TransferBlockSize = 1;
1267 ataCdb->generic.RegisterSelect = REG_COMMAND; 1290 ataCdb->generic.RegisterSelect = REG_COMMAND;
1268 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS; 1291 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
1269 srb->request_bufflen = 0; 1292 isd200_srb_set_bufflen(srb, 0);
1270 } else { 1293 } else {
1271 US_DEBUGP(" Media Status not supported, just report okay\n"); 1294 US_DEBUGP(" Media Status not supported, just report okay\n");
1272 srb->result = SAM_STAT_GOOD; 1295 srb->result = SAM_STAT_GOOD;
@@ -1284,7 +1307,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
1284 ataCdb->generic.TransferBlockSize = 1; 1307 ataCdb->generic.TransferBlockSize = 1;
1285 ataCdb->generic.RegisterSelect = REG_COMMAND; 1308 ataCdb->generic.RegisterSelect = REG_COMMAND;
1286 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS; 1309 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
1287 srb->request_bufflen = 0; 1310 isd200_srb_set_bufflen(srb, 0);
1288 } else { 1311 } else {
1289 US_DEBUGP(" Media Status not supported, just report okay\n"); 1312 US_DEBUGP(" Media Status not supported, just report okay\n");
1290 srb->result = SAM_STAT_GOOD; 1313 srb->result = SAM_STAT_GOOD;
@@ -1390,7 +1413,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
1390 ataCdb->generic.RegisterSelect = REG_COMMAND; 1413 ataCdb->generic.RegisterSelect = REG_COMMAND;
1391 ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ? 1414 ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
1392 WIN_DOORLOCK : WIN_DOORUNLOCK; 1415 WIN_DOORLOCK : WIN_DOORUNLOCK;
1393 srb->request_bufflen = 0; 1416 isd200_srb_set_bufflen(srb, 0);
1394 } else { 1417 } else {
1395 US_DEBUGP(" Not removeable media, just report okay\n"); 1418 US_DEBUGP(" Not removeable media, just report okay\n");
1396 srb->result = SAM_STAT_GOOD; 1419 srb->result = SAM_STAT_GOOD;
@@ -1416,7 +1439,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
1416 ataCdb->generic.TransferBlockSize = 1; 1439 ataCdb->generic.TransferBlockSize = 1;
1417 ataCdb->generic.RegisterSelect = REG_COMMAND; 1440 ataCdb->generic.RegisterSelect = REG_COMMAND;
1418 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS; 1441 ataCdb->write.CommandByte = ATA_COMMAND_GET_MEDIA_STATUS;
1419 srb->request_bufflen = 0; 1442 isd200_srb_set_bufflen(srb, 0);
1420 } else { 1443 } else {
1421 US_DEBUGP(" Nothing to do, just report okay\n"); 1444 US_DEBUGP(" Nothing to do, just report okay\n");
1422 srb->result = SAM_STAT_GOOD; 1445 srb->result = SAM_STAT_GOOD;
@@ -1525,7 +1548,7 @@ int isd200_Initialization(struct us_data *us)
1525 1548
1526void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) 1549void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
1527{ 1550{
1528 int sendToTransport = 1; 1551 int sendToTransport = 1, orig_bufflen;
1529 union ata_cdb ataCdb; 1552 union ata_cdb ataCdb;
1530 1553
1531 /* Make sure driver was initialized */ 1554 /* Make sure driver was initialized */
@@ -1533,11 +1556,14 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
1533 if (us->extra == NULL) 1556 if (us->extra == NULL)
1534 US_DEBUGP("ERROR Driver not initialized\n"); 1557 US_DEBUGP("ERROR Driver not initialized\n");
1535 1558
1536 /* Convert command */ 1559 scsi_set_resid(srb, 0);
1537 srb->resid = 0; 1560 /* scsi_bufflen might change in protocol translation to ata */
1561 orig_bufflen = scsi_bufflen(srb);
1538 sendToTransport = isd200_scsi_to_ata(srb, us, &ataCdb); 1562 sendToTransport = isd200_scsi_to_ata(srb, us, &ataCdb);
1539 1563
1540 /* send the command to the transport layer */ 1564 /* send the command to the transport layer */
1541 if (sendToTransport) 1565 if (sendToTransport)
1542 isd200_invoke_transport(us, srb, &ataCdb); 1566 isd200_invoke_transport(us, srb, &ataCdb);
1567
1568 isd200_srb_set_bufflen(srb, orig_bufflen);
1543} 1569}