diff options
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 325 |
1 files changed, 213 insertions, 112 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index ccdf440021fb..83bfab73ff65 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -133,6 +133,7 @@ struct inquiry_data { | |||
133 | 133 | ||
134 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); | 134 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); |
135 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); | 135 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); |
136 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); | ||
136 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); | 137 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); |
137 | #ifdef AAC_DETAILED_STATUS_INFO | 138 | #ifdef AAC_DETAILED_STATUS_INFO |
138 | static char *aac_get_status_string(u32 status); | 139 | static char *aac_get_status_string(u32 status); |
@@ -348,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd) | |||
348 | spin_unlock_irqrestore(host->host_lock, cpu_flags); | 349 | spin_unlock_irqrestore(host->host_lock, cpu_flags); |
349 | } | 350 | } |
350 | 351 | ||
352 | static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) | ||
353 | { | ||
354 | void *buf; | ||
355 | unsigned int transfer_len; | ||
356 | struct scatterlist *sg = scsicmd->request_buffer; | ||
357 | |||
358 | if (scsicmd->use_sg) { | ||
359 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | ||
360 | transfer_len = min(sg->length, len + offset); | ||
361 | } else { | ||
362 | buf = scsicmd->request_buffer; | ||
363 | transfer_len = min(scsicmd->request_bufflen, len + offset); | ||
364 | } | ||
365 | |||
366 | memcpy(buf + offset, data, transfer_len - offset); | ||
367 | |||
368 | if (scsicmd->use_sg) | ||
369 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
370 | |||
371 | } | ||
372 | |||
351 | static void get_container_name_callback(void *context, struct fib * fibptr) | 373 | static void get_container_name_callback(void *context, struct fib * fibptr) |
352 | { | 374 | { |
353 | struct aac_get_name_resp * get_name_reply; | 375 | struct aac_get_name_resp * get_name_reply; |
@@ -363,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
363 | /* Failure is irrelevant, using default value instead */ | 385 | /* Failure is irrelevant, using default value instead */ |
364 | if ((le32_to_cpu(get_name_reply->status) == CT_OK) | 386 | if ((le32_to_cpu(get_name_reply->status) == CT_OK) |
365 | && (get_name_reply->data[0] != '\0')) { | 387 | && (get_name_reply->data[0] != '\0')) { |
366 | int count; | 388 | char *sp = get_name_reply->data; |
367 | char * dp; | ||
368 | char * sp = get_name_reply->data; | ||
369 | sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; | 389 | sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0'; |
370 | while (*sp == ' ') | 390 | while (*sp == ' ') |
371 | ++sp; | 391 | ++sp; |
372 | count = sizeof(((struct inquiry_data *)NULL)->inqd_pid); | 392 | if (*sp) { |
373 | dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid; | 393 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; |
374 | if (*sp) do { | 394 | int count = sizeof(d); |
375 | *dp++ = (*sp) ? *sp++ : ' '; | 395 | char *dp = d; |
376 | } while (--count > 0); | 396 | do { |
397 | *dp++ = (*sp) ? *sp++ : ' '; | ||
398 | } while (--count > 0); | ||
399 | aac_internal_transfer(scsicmd, d, | ||
400 | offsetof(struct inquiry_data, inqd_pid), sizeof(d)); | ||
401 | } | ||
377 | } | 402 | } |
403 | |||
378 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 404 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
379 | 405 | ||
380 | fib_complete(fibptr); | 406 | fib_complete(fibptr); |
@@ -777,34 +803,36 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
777 | /* | 803 | /* |
778 | * 57 scatter gather elements | 804 | * 57 scatter gather elements |
779 | */ | 805 | */ |
780 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - | 806 | if (!(dev->raw_io_interface)) { |
781 | sizeof(struct aac_fibhdr) - | 807 | dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - |
782 | sizeof(struct aac_write) + sizeof(struct sgmap)) / | ||
783 | sizeof(struct sgmap); | ||
784 | if (dev->dac_support) { | ||
785 | /* | ||
786 | * 38 scatter gather elements | ||
787 | */ | ||
788 | dev->scsi_host_ptr->sg_tablesize = | ||
789 | (dev->max_fib_size - | ||
790 | sizeof(struct aac_fibhdr) - | 808 | sizeof(struct aac_fibhdr) - |
791 | sizeof(struct aac_write64) + | 809 | sizeof(struct aac_write) + sizeof(struct sgmap)) / |
792 | sizeof(struct sgmap64)) / | 810 | sizeof(struct sgmap); |
793 | sizeof(struct sgmap64); | 811 | if (dev->dac_support) { |
794 | } | 812 | /* |
795 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | 813 | * 38 scatter gather elements |
796 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | 814 | */ |
797 | /* | 815 | dev->scsi_host_ptr->sg_tablesize = |
798 | * Worst case size that could cause sg overflow when | 816 | (dev->max_fib_size - |
799 | * we break up SG elements that are larger than 64KB. | 817 | sizeof(struct aac_fibhdr) - |
800 | * Would be nice if we could tell the SCSI layer what | 818 | sizeof(struct aac_write64) + |
801 | * the maximum SG element size can be. Worst case is | 819 | sizeof(struct sgmap64)) / |
802 | * (sg_tablesize-1) 4KB elements with one 64KB | 820 | sizeof(struct sgmap64); |
803 | * element. | 821 | } |
804 | * 32bit -> 468 or 238KB 64bit -> 424 or 212KB | 822 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; |
805 | */ | 823 | if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { |
806 | dev->scsi_host_ptr->max_sectors = | 824 | /* |
807 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | 825 | * Worst case size that could cause sg overflow when |
826 | * we break up SG elements that are larger than 64KB. | ||
827 | * Would be nice if we could tell the SCSI layer what | ||
828 | * the maximum SG element size can be. Worst case is | ||
829 | * (sg_tablesize-1) 4KB elements with one 64KB | ||
830 | * element. | ||
831 | * 32bit -> 468 or 238KB 64bit -> 424 or 212KB | ||
832 | */ | ||
833 | dev->scsi_host_ptr->max_sectors = | ||
834 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | ||
835 | } | ||
808 | } | 836 | } |
809 | 837 | ||
810 | fib_complete(fibptr); | 838 | fib_complete(fibptr); |
@@ -814,12 +842,11 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
814 | } | 842 | } |
815 | 843 | ||
816 | 844 | ||
817 | static void read_callback(void *context, struct fib * fibptr) | 845 | static void io_callback(void *context, struct fib * fibptr) |
818 | { | 846 | { |
819 | struct aac_dev *dev; | 847 | struct aac_dev *dev; |
820 | struct aac_read_reply *readreply; | 848 | struct aac_read_reply *readreply; |
821 | struct scsi_cmnd *scsicmd; | 849 | struct scsi_cmnd *scsicmd; |
822 | u32 lba; | ||
823 | u32 cid; | 850 | u32 cid; |
824 | 851 | ||
825 | scsicmd = (struct scsi_cmnd *) context; | 852 | scsicmd = (struct scsi_cmnd *) context; |
@@ -827,8 +854,7 @@ static void read_callback(void *context, struct fib * fibptr) | |||
827 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 854 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
828 | cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); | 855 | cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); |
829 | 856 | ||
830 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | 857 | dprintk((KERN_DEBUG "io_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3], jiffies)); |
831 | dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); | ||
832 | 858 | ||
833 | if (fibptr == NULL) | 859 | if (fibptr == NULL) |
834 | BUG(); | 860 | BUG(); |
@@ -847,7 +873,7 @@ static void read_callback(void *context, struct fib * fibptr) | |||
847 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 873 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
848 | else { | 874 | else { |
849 | #ifdef AAC_DETAILED_STATUS_INFO | 875 | #ifdef AAC_DETAILED_STATUS_INFO |
850 | printk(KERN_WARNING "read_callback: io failed, status = %d\n", | 876 | printk(KERN_WARNING "io_callback: io failed, status = %d\n", |
851 | le32_to_cpu(readreply->status)); | 877 | le32_to_cpu(readreply->status)); |
852 | #endif | 878 | #endif |
853 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | 879 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; |
@@ -867,53 +893,6 @@ static void read_callback(void *context, struct fib * fibptr) | |||
867 | aac_io_done(scsicmd); | 893 | aac_io_done(scsicmd); |
868 | } | 894 | } |
869 | 895 | ||
870 | static void write_callback(void *context, struct fib * fibptr) | ||
871 | { | ||
872 | struct aac_dev *dev; | ||
873 | struct aac_write_reply *writereply; | ||
874 | struct scsi_cmnd *scsicmd; | ||
875 | u32 lba; | ||
876 | u32 cid; | ||
877 | |||
878 | scsicmd = (struct scsi_cmnd *) context; | ||
879 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | ||
880 | cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); | ||
881 | |||
882 | lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; | ||
883 | dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); | ||
884 | if (fibptr == NULL) | ||
885 | BUG(); | ||
886 | |||
887 | if(scsicmd->use_sg) | ||
888 | pci_unmap_sg(dev->pdev, | ||
889 | (struct scatterlist *)scsicmd->buffer, | ||
890 | scsicmd->use_sg, | ||
891 | scsicmd->sc_data_direction); | ||
892 | else if(scsicmd->request_bufflen) | ||
893 | pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle, | ||
894 | scsicmd->request_bufflen, | ||
895 | scsicmd->sc_data_direction); | ||
896 | |||
897 | writereply = (struct aac_write_reply *) fib_data(fibptr); | ||
898 | if (le32_to_cpu(writereply->status) == ST_OK) | ||
899 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | ||
900 | else { | ||
901 | printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); | ||
902 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; | ||
903 | set_sense((u8 *) &dev->fsa_dev[cid].sense_data, | ||
904 | HARDWARE_ERROR, | ||
905 | SENCODE_INTERNAL_TARGET_FAILURE, | ||
906 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, | ||
907 | 0, 0); | ||
908 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
909 | sizeof(struct sense_data)); | ||
910 | } | ||
911 | |||
912 | fib_complete(fibptr); | ||
913 | fib_free(fibptr); | ||
914 | aac_io_done(scsicmd); | ||
915 | } | ||
916 | |||
917 | static int aac_read(struct scsi_cmnd * scsicmd, int cid) | 896 | static int aac_read(struct scsi_cmnd * scsicmd, int cid) |
918 | { | 897 | { |
919 | u32 lba; | 898 | u32 lba; |
@@ -954,7 +933,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
954 | 933 | ||
955 | fib_init(cmd_fibcontext); | 934 | fib_init(cmd_fibcontext); |
956 | 935 | ||
957 | if (dev->dac_support == 1) { | 936 | if (dev->raw_io_interface) { |
937 | struct aac_raw_io *readcmd; | ||
938 | readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
939 | readcmd->block[0] = cpu_to_le32(lba); | ||
940 | readcmd->block[1] = 0; | ||
941 | readcmd->count = cpu_to_le32(count<<9); | ||
942 | readcmd->cid = cpu_to_le16(cid); | ||
943 | readcmd->flags = cpu_to_le16(1); | ||
944 | readcmd->bpTotal = 0; | ||
945 | readcmd->bpComplete = 0; | ||
946 | |||
947 | aac_build_sgraw(scsicmd, &readcmd->sg); | ||
948 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
949 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) | ||
950 | BUG(); | ||
951 | /* | ||
952 | * Now send the Fib to the adapter | ||
953 | */ | ||
954 | status = fib_send(ContainerRawIo, | ||
955 | cmd_fibcontext, | ||
956 | fibsize, | ||
957 | FsaNormal, | ||
958 | 0, 1, | ||
959 | (fib_callback) io_callback, | ||
960 | (void *) scsicmd); | ||
961 | } else if (dev->dac_support == 1) { | ||
958 | struct aac_read64 *readcmd; | 962 | struct aac_read64 *readcmd; |
959 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); | 963 | readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); |
960 | readcmd->command = cpu_to_le32(VM_CtHostRead64); | 964 | readcmd->command = cpu_to_le32(VM_CtHostRead64); |
@@ -978,7 +982,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
978 | fibsize, | 982 | fibsize, |
979 | FsaNormal, | 983 | FsaNormal, |
980 | 0, 1, | 984 | 0, 1, |
981 | (fib_callback) read_callback, | 985 | (fib_callback) io_callback, |
982 | (void *) scsicmd); | 986 | (void *) scsicmd); |
983 | } else { | 987 | } else { |
984 | struct aac_read *readcmd; | 988 | struct aac_read *readcmd; |
@@ -1002,7 +1006,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) | |||
1002 | fibsize, | 1006 | fibsize, |
1003 | FsaNormal, | 1007 | FsaNormal, |
1004 | 0, 1, | 1008 | 0, 1, |
1005 | (fib_callback) read_callback, | 1009 | (fib_callback) io_callback, |
1006 | (void *) scsicmd); | 1010 | (void *) scsicmd); |
1007 | } | 1011 | } |
1008 | 1012 | ||
@@ -1061,7 +1065,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1061 | } | 1065 | } |
1062 | fib_init(cmd_fibcontext); | 1066 | fib_init(cmd_fibcontext); |
1063 | 1067 | ||
1064 | if(dev->dac_support == 1) { | 1068 | if (dev->raw_io_interface) { |
1069 | struct aac_raw_io *writecmd; | ||
1070 | writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext); | ||
1071 | writecmd->block[0] = cpu_to_le32(lba); | ||
1072 | writecmd->block[1] = 0; | ||
1073 | writecmd->count = cpu_to_le32(count<<9); | ||
1074 | writecmd->cid = cpu_to_le16(cid); | ||
1075 | writecmd->flags = 0; | ||
1076 | writecmd->bpTotal = 0; | ||
1077 | writecmd->bpComplete = 0; | ||
1078 | |||
1079 | aac_build_sgraw(scsicmd, &writecmd->sg); | ||
1080 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
1081 | if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) | ||
1082 | BUG(); | ||
1083 | /* | ||
1084 | * Now send the Fib to the adapter | ||
1085 | */ | ||
1086 | status = fib_send(ContainerRawIo, | ||
1087 | cmd_fibcontext, | ||
1088 | fibsize, | ||
1089 | FsaNormal, | ||
1090 | 0, 1, | ||
1091 | (fib_callback) io_callback, | ||
1092 | (void *) scsicmd); | ||
1093 | } else if (dev->dac_support == 1) { | ||
1065 | struct aac_write64 *writecmd; | 1094 | struct aac_write64 *writecmd; |
1066 | writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); | 1095 | writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); |
1067 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); | 1096 | writecmd->command = cpu_to_le32(VM_CtHostWrite64); |
@@ -1085,7 +1114,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1085 | fibsize, | 1114 | fibsize, |
1086 | FsaNormal, | 1115 | FsaNormal, |
1087 | 0, 1, | 1116 | 0, 1, |
1088 | (fib_callback) write_callback, | 1117 | (fib_callback) io_callback, |
1089 | (void *) scsicmd); | 1118 | (void *) scsicmd); |
1090 | } else { | 1119 | } else { |
1091 | struct aac_write *writecmd; | 1120 | struct aac_write *writecmd; |
@@ -1111,7 +1140,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) | |||
1111 | fibsize, | 1140 | fibsize, |
1112 | FsaNormal, | 1141 | FsaNormal, |
1113 | 0, 1, | 1142 | 0, 1, |
1114 | (fib_callback) write_callback, | 1143 | (fib_callback) io_callback, |
1115 | (void *) scsicmd); | 1144 | (void *) scsicmd); |
1116 | } | 1145 | } |
1117 | 1146 | ||
@@ -1340,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1340 | switch (scsicmd->cmnd[0]) { | 1369 | switch (scsicmd->cmnd[0]) { |
1341 | case INQUIRY: | 1370 | case INQUIRY: |
1342 | { | 1371 | { |
1343 | struct inquiry_data *inq_data_ptr; | 1372 | struct inquiry_data inq_data; |
1344 | 1373 | ||
1345 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); | 1374 | dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); |
1346 | inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer; | 1375 | memset(&inq_data, 0, sizeof (struct inquiry_data)); |
1347 | memset(inq_data_ptr, 0, sizeof (struct inquiry_data)); | ||
1348 | 1376 | ||
1349 | inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */ | 1377 | inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */ |
1350 | inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ | 1378 | inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */ |
1351 | inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ | 1379 | inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */ |
1352 | inq_data_ptr->inqd_len = 31; | 1380 | inq_data.inqd_len = 31; |
1353 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ | 1381 | /*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */ |
1354 | inq_data_ptr->inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ | 1382 | inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */ |
1355 | /* | 1383 | /* |
1356 | * Set the Vendor, Product, and Revision Level | 1384 | * Set the Vendor, Product, and Revision Level |
1357 | * see: <vendor>.c i.e. aac.c | 1385 | * see: <vendor>.c i.e. aac.c |
1358 | */ | 1386 | */ |
1359 | if (scsicmd->device->id == host->this_id) { | 1387 | if (scsicmd->device->id == host->this_id) { |
1360 | setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *))); | 1388 | setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *))); |
1361 | inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ | 1389 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ |
1390 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | ||
1362 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1391 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1363 | scsicmd->scsi_done(scsicmd); | 1392 | scsicmd->scsi_done(scsicmd); |
1364 | return 0; | 1393 | return 0; |
1365 | } | 1394 | } |
1366 | setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type); | 1395 | setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
1367 | inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 1396 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
1397 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | ||
1368 | return aac_get_container_name(scsicmd, cid); | 1398 | return aac_get_container_name(scsicmd, cid); |
1369 | } | 1399 | } |
1370 | case READ_CAPACITY: | 1400 | case READ_CAPACITY: |
1371 | { | 1401 | { |
1372 | u32 capacity; | 1402 | u32 capacity; |
1373 | char *cp; | 1403 | char cp[8]; |
1374 | 1404 | ||
1375 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); | 1405 | dprintk((KERN_DEBUG "READ CAPACITY command.\n")); |
1376 | if (fsa_dev_ptr[cid].size <= 0x100000000LL) | 1406 | if (fsa_dev_ptr[cid].size <= 0x100000000LL) |
1377 | capacity = fsa_dev_ptr[cid].size - 1; | 1407 | capacity = fsa_dev_ptr[cid].size - 1; |
1378 | else | 1408 | else |
1379 | capacity = (u32)-1; | 1409 | capacity = (u32)-1; |
1380 | cp = scsicmd->request_buffer; | 1410 | |
1381 | cp[0] = (capacity >> 24) & 0xff; | 1411 | cp[0] = (capacity >> 24) & 0xff; |
1382 | cp[1] = (capacity >> 16) & 0xff; | 1412 | cp[1] = (capacity >> 16) & 0xff; |
1383 | cp[2] = (capacity >> 8) & 0xff; | 1413 | cp[2] = (capacity >> 8) & 0xff; |
@@ -1386,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1386 | cp[5] = 0; | 1416 | cp[5] = 0; |
1387 | cp[6] = 2; | 1417 | cp[6] = 2; |
1388 | cp[7] = 0; | 1418 | cp[7] = 0; |
1419 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | ||
1389 | 1420 | ||
1390 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1421 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1391 | scsicmd->scsi_done(scsicmd); | 1422 | scsicmd->scsi_done(scsicmd); |
@@ -1395,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1395 | 1426 | ||
1396 | case MODE_SENSE: | 1427 | case MODE_SENSE: |
1397 | { | 1428 | { |
1398 | char *mode_buf; | 1429 | char mode_buf[4]; |
1399 | 1430 | ||
1400 | dprintk((KERN_DEBUG "MODE SENSE command.\n")); | 1431 | dprintk((KERN_DEBUG "MODE SENSE command.\n")); |
1401 | mode_buf = scsicmd->request_buffer; | ||
1402 | mode_buf[0] = 3; /* Mode data length */ | 1432 | mode_buf[0] = 3; /* Mode data length */ |
1403 | mode_buf[1] = 0; /* Medium type - default */ | 1433 | mode_buf[1] = 0; /* Medium type - default */ |
1404 | mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ | 1434 | mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */ |
1405 | mode_buf[3] = 0; /* Block descriptor length */ | 1435 | mode_buf[3] = 0; /* Block descriptor length */ |
1406 | 1436 | ||
1437 | aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); | ||
1407 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1438 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1408 | scsicmd->scsi_done(scsicmd); | 1439 | scsicmd->scsi_done(scsicmd); |
1409 | 1440 | ||
@@ -1411,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1411 | } | 1442 | } |
1412 | case MODE_SENSE_10: | 1443 | case MODE_SENSE_10: |
1413 | { | 1444 | { |
1414 | char *mode_buf; | 1445 | char mode_buf[8]; |
1415 | 1446 | ||
1416 | dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); | 1447 | dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n")); |
1417 | mode_buf = scsicmd->request_buffer; | ||
1418 | mode_buf[0] = 0; /* Mode data length (MSB) */ | 1448 | mode_buf[0] = 0; /* Mode data length (MSB) */ |
1419 | mode_buf[1] = 6; /* Mode data length (LSB) */ | 1449 | mode_buf[1] = 6; /* Mode data length (LSB) */ |
1420 | mode_buf[2] = 0; /* Medium type - default */ | 1450 | mode_buf[2] = 0; /* Medium type - default */ |
@@ -1423,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1423 | mode_buf[5] = 0; /* reserved */ | 1453 | mode_buf[5] = 0; /* reserved */ |
1424 | mode_buf[6] = 0; /* Block descriptor length (MSB) */ | 1454 | mode_buf[6] = 0; /* Block descriptor length (MSB) */ |
1425 | mode_buf[7] = 0; /* Block descriptor length (LSB) */ | 1455 | mode_buf[7] = 0; /* Block descriptor length (LSB) */ |
1456 | aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf)); | ||
1426 | 1457 | ||
1427 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1458 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1428 | scsicmd->scsi_done(scsicmd); | 1459 | scsicmd->scsi_done(scsicmd); |
@@ -1894,7 +1925,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) | |||
1894 | srbcmd->id = cpu_to_le32(scsicmd->device->id); | 1925 | srbcmd->id = cpu_to_le32(scsicmd->device->id); |
1895 | srbcmd->lun = cpu_to_le32(scsicmd->device->lun); | 1926 | srbcmd->lun = cpu_to_le32(scsicmd->device->lun); |
1896 | srbcmd->flags = cpu_to_le32(flag); | 1927 | srbcmd->flags = cpu_to_le32(flag); |
1897 | timeout = (scsicmd->timeout-jiffies)/HZ; | 1928 | timeout = scsicmd->timeout_per_command/HZ; |
1898 | if(timeout == 0){ | 1929 | if(timeout == 0){ |
1899 | timeout = 1; | 1930 | timeout = 1; |
1900 | } | 1931 | } |
@@ -2077,6 +2108,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p | |||
2077 | return byte_count; | 2108 | return byte_count; |
2078 | } | 2109 | } |
2079 | 2110 | ||
2111 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg) | ||
2112 | { | ||
2113 | struct Scsi_Host *host = scsicmd->device->host; | ||
2114 | struct aac_dev *dev = (struct aac_dev *)host->hostdata; | ||
2115 | unsigned long byte_count = 0; | ||
2116 | |||
2117 | // Get rid of old data | ||
2118 | psg->count = 0; | ||
2119 | psg->sg[0].next = 0; | ||
2120 | psg->sg[0].prev = 0; | ||
2121 | psg->sg[0].addr[0] = 0; | ||
2122 | psg->sg[0].addr[1] = 0; | ||
2123 | psg->sg[0].count = 0; | ||
2124 | psg->sg[0].flags = 0; | ||
2125 | if (scsicmd->use_sg) { | ||
2126 | struct scatterlist *sg; | ||
2127 | int i; | ||
2128 | int sg_count; | ||
2129 | sg = (struct scatterlist *) scsicmd->request_buffer; | ||
2130 | |||
2131 | sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg, | ||
2132 | scsicmd->sc_data_direction); | ||
2133 | |||
2134 | for (i = 0; i < sg_count; i++) { | ||
2135 | int count = sg_dma_len(sg); | ||
2136 | u64 addr = sg_dma_address(sg); | ||
2137 | psg->sg[i].next = 0; | ||
2138 | psg->sg[i].prev = 0; | ||
2139 | psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32)); | ||
2140 | psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); | ||
2141 | psg->sg[i].count = cpu_to_le32(count); | ||
2142 | psg->sg[i].flags = 0; | ||
2143 | byte_count += count; | ||
2144 | sg++; | ||
2145 | } | ||
2146 | psg->count = cpu_to_le32(sg_count); | ||
2147 | /* hba wants the size to be exact */ | ||
2148 | if(byte_count > scsicmd->request_bufflen){ | ||
2149 | u32 temp = le32_to_cpu(psg->sg[i-1].count) - | ||
2150 | (byte_count - scsicmd->request_bufflen); | ||
2151 | psg->sg[i-1].count = cpu_to_le32(temp); | ||
2152 | byte_count = scsicmd->request_bufflen; | ||
2153 | } | ||
2154 | /* Check for command underflow */ | ||
2155 | if(scsicmd->underflow && (byte_count < scsicmd->underflow)){ | ||
2156 | printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n", | ||
2157 | byte_count, scsicmd->underflow); | ||
2158 | } | ||
2159 | } | ||
2160 | else if(scsicmd->request_bufflen) { | ||
2161 | int count; | ||
2162 | u64 addr; | ||
2163 | scsicmd->SCp.dma_handle = pci_map_single(dev->pdev, | ||
2164 | scsicmd->request_buffer, | ||
2165 | scsicmd->request_bufflen, | ||
2166 | scsicmd->sc_data_direction); | ||
2167 | addr = scsicmd->SCp.dma_handle; | ||
2168 | count = scsicmd->request_bufflen; | ||
2169 | psg->count = cpu_to_le32(1); | ||
2170 | psg->sg[0].next = 0; | ||
2171 | psg->sg[0].prev = 0; | ||
2172 | psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32)); | ||
2173 | psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff)); | ||
2174 | psg->sg[0].count = cpu_to_le32(count); | ||
2175 | psg->sg[0].flags = 0; | ||
2176 | byte_count = scsicmd->request_bufflen; | ||
2177 | } | ||
2178 | return byte_count; | ||
2179 | } | ||
2180 | |||
2080 | #ifdef AAC_DETAILED_STATUS_INFO | 2181 | #ifdef AAC_DETAILED_STATUS_INFO |
2081 | 2182 | ||
2082 | struct aac_srb_status_info { | 2183 | struct aac_srb_status_info { |