aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/aachba.c
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-08-03 18:39:49 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-08-05 17:57:56 -0400
commit0e68c00373f61fcdee453f6c9878e3390fc0f0ce (patch)
tree7172e827bccfa4b9c04fc11ddc54ae34a6376562 /drivers/scsi/aacraid/aachba.c
parent12a26d0879d8a4502425037e9013b1f64ed669b7 (diff)
[SCSI] aacraid: sgraw command support
Received from Mark Salyzyn from Adaptec: This patch adds support for the new raw io command. This new command offers much larger io commands, is more friendly to the internal firmware structure requiring less translation efforts by the firmware and offers support for targets greater than 2TB (patch to support >2TB will be sent in the future). Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r--drivers/scsi/aacraid/aachba.c181
1 files changed, 152 insertions, 29 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index b03c8dee76b7..d6c999cd7f78 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -133,6 +133,7 @@ struct inquiry_data {
133 133
134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); 134static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); 135static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
136static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
136static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); 137static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
137#ifdef AAC_DETAILED_STATUS_INFO 138#ifdef AAC_DETAILED_STATUS_INFO
138static char *aac_get_status_string(u32 status); 139static char *aac_get_status_string(u32 status);
@@ -777,34 +778,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
777 /* 778 /*
778 * 57 scatter gather elements 779 * 57 scatter gather elements
779 */ 780 */
780 dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size - 781 if (!(dev->raw_io_interface)) {
781 sizeof(struct aac_fibhdr) - 782 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) - 783 sizeof(struct aac_fibhdr) -
791 sizeof(struct aac_write64) + 784 sizeof(struct aac_write) + sizeof(struct sgmap)) /
792 sizeof(struct sgmap64)) / 785 sizeof(struct sgmap);
793 sizeof(struct sgmap64); 786 if (dev->dac_support) {
794 } 787 /*
795 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; 788 * 38 scatter gather elements
796 if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { 789 */
797 /* 790 dev->scsi_host_ptr->sg_tablesize =
798 * Worst case size that could cause sg overflow when 791 (dev->max_fib_size -
799 * we break up SG elements that are larger than 64KB. 792 sizeof(struct aac_fibhdr) -
800 * Would be nice if we could tell the SCSI layer what 793 sizeof(struct aac_write64) +
801 * the maximum SG element size can be. Worst case is 794 sizeof(struct sgmap64)) /
802 * (sg_tablesize-1) 4KB elements with one 64KB 795 sizeof(struct sgmap64);
803 * element. 796 }
804 * 32bit -> 468 or 238KB 64bit -> 424 or 212KB 797 dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
805 */ 798 if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
806 dev->scsi_host_ptr->max_sectors = 799 /*
807 (dev->scsi_host_ptr->sg_tablesize * 8) + 112; 800 * Worst case size that could cause sg overflow when
801 * we break up SG elements that are larger than 64KB.
802 * Would be nice if we could tell the SCSI layer what
803 * the maximum SG element size can be. Worst case is
804 * (sg_tablesize-1) 4KB elements with one 64KB
805 * element.
806 * 32bit -> 468 or 238KB 64bit -> 424 or 212KB
807 */
808 dev->scsi_host_ptr->max_sectors =
809 (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
810 }
808 } 811 }
809 812
810 fib_complete(fibptr); 813 fib_complete(fibptr);
@@ -905,7 +908,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
905 908
906 fib_init(cmd_fibcontext); 909 fib_init(cmd_fibcontext);
907 910
908 if (dev->dac_support == 1) { 911 if (dev->raw_io_interface) {
912 struct aac_raw_io *readcmd;
913 readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
914 readcmd->block[0] = cpu_to_le32(lba);
915 readcmd->block[1] = 0;
916 readcmd->count = cpu_to_le32(count<<9);
917 readcmd->cid = cpu_to_le16(cid);
918 readcmd->flags = cpu_to_le16(1);
919 readcmd->bpTotal = 0;
920 readcmd->bpComplete = 0;
921
922 aac_build_sgraw(scsicmd, &readcmd->sg);
923 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
924 if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
925 BUG();
926 /*
927 * Now send the Fib to the adapter
928 */
929 status = fib_send(ContainerRawIo,
930 cmd_fibcontext,
931 fibsize,
932 FsaNormal,
933 0, 1,
934 (fib_callback) io_callback,
935 (void *) scsicmd);
936 } else if (dev->dac_support == 1) {
909 struct aac_read64 *readcmd; 937 struct aac_read64 *readcmd;
910 readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); 938 readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
911 readcmd->command = cpu_to_le32(VM_CtHostRead64); 939 readcmd->command = cpu_to_le32(VM_CtHostRead64);
@@ -1012,7 +1040,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
1012 } 1040 }
1013 fib_init(cmd_fibcontext); 1041 fib_init(cmd_fibcontext);
1014 1042
1015 if(dev->dac_support == 1) { 1043 if (dev->raw_io_interface) {
1044 struct aac_raw_io *writecmd;
1045 writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
1046 writecmd->block[0] = cpu_to_le32(lba);
1047 writecmd->block[1] = 0;
1048 writecmd->count = cpu_to_le32(count<<9);
1049 writecmd->cid = cpu_to_le16(cid);
1050 writecmd->flags = 0;
1051 writecmd->bpTotal = 0;
1052 writecmd->bpComplete = 0;
1053
1054 aac_build_sgraw(scsicmd, &writecmd->sg);
1055 fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
1056 if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
1057 BUG();
1058 /*
1059 * Now send the Fib to the adapter
1060 */
1061 status = fib_send(ContainerRawIo,
1062 cmd_fibcontext,
1063 fibsize,
1064 FsaNormal,
1065 0, 1,
1066 (fib_callback) io_callback,
1067 (void *) scsicmd);
1068 } else if (dev->dac_support == 1) {
1016 struct aac_write64 *writecmd; 1069 struct aac_write64 *writecmd;
1017 writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); 1070 writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
1018 writecmd->command = cpu_to_le32(VM_CtHostWrite64); 1071 writecmd->command = cpu_to_le32(VM_CtHostWrite64);
@@ -2028,6 +2081,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
2028 return byte_count; 2081 return byte_count;
2029} 2082}
2030 2083
2084static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg)
2085{
2086 struct Scsi_Host *host = scsicmd->device->host;
2087 struct aac_dev *dev = (struct aac_dev *)host->hostdata;
2088 unsigned long byte_count = 0;
2089
2090 // Get rid of old data
2091 psg->count = 0;
2092 psg->sg[0].next = 0;
2093 psg->sg[0].prev = 0;
2094 psg->sg[0].addr[0] = 0;
2095 psg->sg[0].addr[1] = 0;
2096 psg->sg[0].count = 0;
2097 psg->sg[0].flags = 0;
2098 if (scsicmd->use_sg) {
2099 struct scatterlist *sg;
2100 int i;
2101 int sg_count;
2102 sg = (struct scatterlist *) scsicmd->request_buffer;
2103
2104 sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
2105 scsicmd->sc_data_direction);
2106
2107 for (i = 0; i < sg_count; i++) {
2108 int count = sg_dma_len(sg);
2109 u64 addr = sg_dma_address(sg);
2110 psg->sg[i].next = 0;
2111 psg->sg[i].prev = 0;
2112 psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));
2113 psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
2114 psg->sg[i].count = cpu_to_le32(count);
2115 psg->sg[i].flags = 0;
2116 byte_count += count;
2117 sg++;
2118 }
2119 psg->count = cpu_to_le32(sg_count);
2120 /* hba wants the size to be exact */
2121 if(byte_count > scsicmd->request_bufflen){
2122 u32 temp = le32_to_cpu(psg->sg[i-1].count) -
2123 (byte_count - scsicmd->request_bufflen);
2124 psg->sg[i-1].count = cpu_to_le32(temp);
2125 byte_count = scsicmd->request_bufflen;
2126 }
2127 /* Check for command underflow */
2128 if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
2129 printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
2130 byte_count, scsicmd->underflow);
2131 }
2132 }
2133 else if(scsicmd->request_bufflen) {
2134 int count;
2135 u64 addr;
2136 scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
2137 scsicmd->request_buffer,
2138 scsicmd->request_bufflen,
2139 scsicmd->sc_data_direction);
2140 addr = scsicmd->SCp.dma_handle;
2141 count = scsicmd->request_bufflen;
2142 psg->count = cpu_to_le32(1);
2143 psg->sg[0].next = 0;
2144 psg->sg[0].prev = 0;
2145 psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32));
2146 psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
2147 psg->sg[0].count = cpu_to_le32(count);
2148 psg->sg[0].flags = 0;
2149 byte_count = scsicmd->request_bufflen;
2150 }
2151 return byte_count;
2152}
2153
2031#ifdef AAC_DETAILED_STATUS_INFO 2154#ifdef AAC_DETAILED_STATUS_INFO
2032 2155
2033struct aac_srb_status_info { 2156struct aac_srb_status_info {