diff options
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 425a61c79bb6..c1a79c3f4712 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -103,7 +103,7 @@ enum { | |||
103 | MU_REQ_COUNT = (MU_MAX_REQUEST + 1), | 103 | MU_REQ_COUNT = (MU_MAX_REQUEST + 1), |
104 | MU_STATUS_COUNT = (MU_MAX_REQUEST + 1), | 104 | MU_STATUS_COUNT = (MU_MAX_REQUEST + 1), |
105 | 105 | ||
106 | STEX_CDB_LENGTH = MAX_COMMAND_SIZE, | 106 | STEX_CDB_LENGTH = 16, |
107 | REQ_VARIABLE_LEN = 1024, | 107 | REQ_VARIABLE_LEN = 1024, |
108 | STATUS_VAR_LEN = 128, | 108 | STATUS_VAR_LEN = 128, |
109 | ST_CAN_QUEUE = MU_MAX_REQUEST, | 109 | ST_CAN_QUEUE = MU_MAX_REQUEST, |
@@ -114,6 +114,9 @@ enum { | |||
114 | SG_CF_EOT = 0x80, /* end of table */ | 114 | SG_CF_EOT = 0x80, /* end of table */ |
115 | SG_CF_64B = 0x40, /* 64 bit item */ | 115 | SG_CF_64B = 0x40, /* 64 bit item */ |
116 | SG_CF_HOST = 0x20, /* sg in host memory */ | 116 | SG_CF_HOST = 0x20, /* sg in host memory */ |
117 | MSG_DATA_DIR_ND = 0, | ||
118 | MSG_DATA_DIR_IN = 1, | ||
119 | MSG_DATA_DIR_OUT = 2, | ||
117 | 120 | ||
118 | st_shasta = 0, | 121 | st_shasta = 0, |
119 | st_vsc = 1, | 122 | st_vsc = 1, |
@@ -123,7 +126,7 @@ enum { | |||
123 | 126 | ||
124 | PASSTHRU_REQ_TYPE = 0x00000001, | 127 | PASSTHRU_REQ_TYPE = 0x00000001, |
125 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, | 128 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, |
126 | ST_INTERNAL_TIMEOUT = 30, | 129 | ST_INTERNAL_TIMEOUT = 180, |
127 | 130 | ||
128 | ST_TO_CMD = 0, | 131 | ST_TO_CMD = 0, |
129 | ST_FROM_CMD = 1, | 132 | ST_FROM_CMD = 1, |
@@ -194,7 +197,7 @@ struct req_msg { | |||
194 | u8 target; | 197 | u8 target; |
195 | u8 task_attr; | 198 | u8 task_attr; |
196 | u8 task_manage; | 199 | u8 task_manage; |
197 | u8 prd_entry; | 200 | u8 data_dir; |
198 | u8 payload_sz; /* payload size in 4-byte, not used */ | 201 | u8 payload_sz; /* payload size in 4-byte, not used */ |
199 | u8 cdb[STEX_CDB_LENGTH]; | 202 | u8 cdb[STEX_CDB_LENGTH]; |
200 | u8 variable[REQ_VARIABLE_LEN]; | 203 | u8 variable[REQ_VARIABLE_LEN]; |
@@ -318,8 +321,8 @@ MODULE_VERSION(ST_DRIVER_VERSION); | |||
318 | static void stex_gettime(__le32 *time) | 321 | static void stex_gettime(__le32 *time) |
319 | { | 322 | { |
320 | struct timeval tv; | 323 | struct timeval tv; |
321 | do_gettimeofday(&tv); | ||
322 | 324 | ||
325 | do_gettimeofday(&tv); | ||
323 | *time = cpu_to_le32(tv.tv_sec & 0xffffffff); | 326 | *time = cpu_to_le32(tv.tv_sec & 0xffffffff); |
324 | *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16); | 327 | *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16); |
325 | } | 328 | } |
@@ -340,7 +343,7 @@ static void stex_invalid_field(struct scsi_cmnd *cmd, | |||
340 | { | 343 | { |
341 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 344 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
342 | 345 | ||
343 | /* "Invalid field in cbd" */ | 346 | /* "Invalid field in cdb" */ |
344 | scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, | 347 | scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, |
345 | 0x0); | 348 | 0x0); |
346 | done(cmd); | 349 | done(cmd); |
@@ -469,6 +472,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
469 | unsigned int id,lun; | 472 | unsigned int id,lun; |
470 | struct req_msg *req; | 473 | struct req_msg *req; |
471 | u16 tag; | 474 | u16 tag; |
475 | |||
472 | host = cmd->device->host; | 476 | host = cmd->device->host; |
473 | id = cmd->device->id; | 477 | id = cmd->device->id; |
474 | lun = cmd->device->lun; | 478 | lun = cmd->device->lun; |
@@ -480,6 +484,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
480 | static char ms10_caching_page[12] = | 484 | static char ms10_caching_page[12] = |
481 | { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 }; | 485 | { 0, 0x12, 0, 0, 0, 0, 0, 0, 0x8, 0xa, 0x4, 0 }; |
482 | unsigned char page; | 486 | unsigned char page; |
487 | |||
483 | page = cmd->cmnd[2] & 0x3f; | 488 | page = cmd->cmnd[2] & 0x3f; |
484 | if (page == 0x8 || page == 0x3f) { | 489 | if (page == 0x8 || page == 0x3f) { |
485 | scsi_sg_copy_from_buffer(cmd, ms10_caching_page, | 490 | scsi_sg_copy_from_buffer(cmd, ms10_caching_page, |
@@ -523,6 +528,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
523 | if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { | 528 | if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { |
524 | struct st_drvver ver; | 529 | struct st_drvver ver; |
525 | size_t cp_len = sizeof(ver); | 530 | size_t cp_len = sizeof(ver); |
531 | |||
526 | ver.major = ST_VER_MAJOR; | 532 | ver.major = ST_VER_MAJOR; |
527 | ver.minor = ST_VER_MINOR; | 533 | ver.minor = ST_VER_MINOR; |
528 | ver.oem = ST_OEM; | 534 | ver.oem = ST_OEM; |
@@ -556,6 +562,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
556 | /* cdb */ | 562 | /* cdb */ |
557 | memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); | 563 | memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH); |
558 | 564 | ||
565 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) | ||
566 | req->data_dir = MSG_DATA_DIR_IN; | ||
567 | else if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
568 | req->data_dir = MSG_DATA_DIR_OUT; | ||
569 | else | ||
570 | req->data_dir = MSG_DATA_DIR_ND; | ||
571 | |||
559 | hba->ccb[tag].cmd = cmd; | 572 | hba->ccb[tag].cmd = cmd; |
560 | hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; | 573 | hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE; |
561 | hba->ccb[tag].sense_buffer = cmd->sense_buffer; | 574 | hba->ccb[tag].sense_buffer = cmd->sense_buffer; |
@@ -614,6 +627,7 @@ static void stex_copy_data(struct st_ccb *ccb, | |||
614 | struct status_msg *resp, unsigned int variable) | 627 | struct status_msg *resp, unsigned int variable) |
615 | { | 628 | { |
616 | size_t count = variable; | 629 | size_t count = variable; |
630 | |||
617 | if (resp->scsi_status != SAM_STAT_GOOD) { | 631 | if (resp->scsi_status != SAM_STAT_GOOD) { |
618 | if (ccb->sense_buffer != NULL) | 632 | if (ccb->sense_buffer != NULL) |
619 | memcpy(ccb->sense_buffer, resp->variable, | 633 | memcpy(ccb->sense_buffer, resp->variable, |
@@ -938,6 +952,7 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
938 | struct st_hba *hba; | 952 | struct st_hba *hba; |
939 | unsigned long flags; | 953 | unsigned long flags; |
940 | unsigned long before; | 954 | unsigned long before; |
955 | |||
941 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; | 956 | hba = (struct st_hba *) &cmd->device->host->hostdata[0]; |
942 | 957 | ||
943 | printk(KERN_INFO DRV_NAME | 958 | printk(KERN_INFO DRV_NAME |
@@ -1022,6 +1037,7 @@ static struct scsi_host_template driver_template = { | |||
1022 | static int stex_set_dma_mask(struct pci_dev * pdev) | 1037 | static int stex_set_dma_mask(struct pci_dev * pdev) |
1023 | { | 1038 | { |
1024 | int ret; | 1039 | int ret; |
1040 | |||
1025 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) | 1041 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) |
1026 | && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) | 1042 | && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) |
1027 | return 0; | 1043 | return 0; |
@@ -1079,7 +1095,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1079 | } | 1095 | } |
1080 | 1096 | ||
1081 | hba->cardtype = (unsigned int) id->driver_data; | 1097 | hba->cardtype = (unsigned int) id->driver_data; |
1082 | if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) | 1098 | if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1)) |
1083 | hba->cardtype = st_vsc1; | 1099 | hba->cardtype = st_vsc1; |
1084 | hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ? | 1100 | hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ? |
1085 | (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); | 1101 | (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); |