aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/scsi/aacraid/aachba.c181
-rw-r--r--drivers/scsi/aacraid/aacraid.h43
2 files changed, 194 insertions, 30 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 {
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 6f4906ee9a5e..bc91e7ce5e59 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -114,6 +114,22 @@ struct user_sgentry64 {
114 u32 count; /* Length. */ 114 u32 count; /* Length. */
115}; 115};
116 116
117struct sgentryraw {
118 __le32 next; /* reserved for F/W use */
119 __le32 prev; /* reserved for F/W use */
120 __le32 addr[2];
121 __le32 count;
122 __le32 flags; /* reserved for F/W use */
123};
124
125struct user_sgentryraw {
126 u32 next; /* reserved for F/W use */
127 u32 prev; /* reserved for F/W use */
128 u32 addr[2];
129 u32 count;
130 u32 flags; /* reserved for F/W use */
131};
132
117/* 133/*
118 * SGMAP 134 * SGMAP
119 * 135 *
@@ -141,6 +157,16 @@ struct user_sgmap64 {
141 struct user_sgentry64 sg[1]; 157 struct user_sgentry64 sg[1];
142}; 158};
143 159
160struct sgmapraw {
161 __le32 count;
162 struct sgentryraw sg[1];
163};
164
165struct user_sgmapraw {
166 u32 count;
167 struct user_sgentryraw sg[1];
168};
169
144struct creation_info 170struct creation_info
145{ 171{
146 u8 buildnum; /* e.g., 588 */ 172 u8 buildnum; /* e.g., 588 */
@@ -355,6 +381,7 @@ struct hw_fib {
355 */ 381 */
356#define ContainerCommand 500 382#define ContainerCommand 500
357#define ContainerCommand64 501 383#define ContainerCommand64 501
384#define ContainerRawIo 502
358/* 385/*
359 * Cluster Commands 386 * Cluster Commands
360 */ 387 */
@@ -986,6 +1013,9 @@ struct aac_dev
986 u8 nondasd_support; 1013 u8 nondasd_support;
987 u8 dac_support; 1014 u8 dac_support;
988 u8 raid_scsi_mode; 1015 u8 raid_scsi_mode;
1016 /* macro side-effects BEWARE */
1017# define raw_io_interface \
1018 init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
989 u8 printf_enabled; 1019 u8 printf_enabled;
990}; 1020};
991 1021
@@ -1164,6 +1194,17 @@ struct aac_write_reply
1164 __le32 committed; 1194 __le32 committed;
1165}; 1195};
1166 1196
1197struct aac_raw_io
1198{
1199 __le32 block[2];
1200 __le32 count;
1201 __le16 cid;
1202 __le16 flags; /* 00 W, 01 R */
1203 __le16 bpTotal; /* reserved for F/W use */
1204 __le16 bpComplete; /* reserved for F/W use */
1205 struct sgmapraw sg;
1206};
1207
1167#define CT_FLUSH_CACHE 129 1208#define CT_FLUSH_CACHE 129
1168struct aac_synchronize { 1209struct aac_synchronize {
1169 __le32 command; /* VM_ContainerConfig */ 1210 __le32 command; /* VM_ContainerConfig */
@@ -1204,7 +1245,7 @@ struct aac_srb
1204}; 1245};
1205 1246
1206/* 1247/*
1207 * This and assocated data structs are used by the 1248 * This and associated data structs are used by the
1208 * ioctl caller and are in cpu order. 1249 * ioctl caller and are in cpu order.
1209 */ 1250 */
1210struct user_aac_srb 1251struct user_aac_srb