diff options
author | Mahesh Rajashekhara <Mahesh_Rajashekhara@pmc-sierra.com> | 2012-07-14 08:48:51 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:59:04 -0400 |
commit | 85d22bbf6787c240921539bba224eb221bfb8ee1 (patch) | |
tree | 364d004282e48cd45d83232e00fddc3cdbec057c | |
parent | fa7250d6945d0f693bef6545682beb7f671f1694 (diff) |
[SCSI] aacraid: Series 7 Async. (performance) mode support
- Series 7 Async. (performance) mode support added
- New scatter/gather list format for Series 7
- Driver converts s/g list to a firmware suitable list for best performance on
Series 7, this can be disabled with driver parameter "aac_convert_sgl" for
testing purposes
- New container read/write command structure for Series 7
- Fast response support for the SCSI pass-through path added
- Async. status response buffer changes
Signed-off-by: Mahesh Rajashekhara <Mahesh_Rajashekhara@pmc-sierra.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 237 | ||||
-rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 74 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 54 | ||||
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 22 | ||||
-rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 6 | ||||
-rw-r--r-- | drivers/scsi/aacraid/linit.c | 2 | ||||
-rw-r--r-- | drivers/scsi/aacraid/src.c | 85 |
8 files changed, 357 insertions, 125 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 52551662d107..d79457ac8bef 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -135,6 +135,8 @@ struct inquiry_data { | |||
135 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); | 135 | static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); |
136 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); | 136 | static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); |
137 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); | 137 | static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg); |
138 | static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max); | ||
139 | static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new); | ||
138 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); | 140 | static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); |
139 | #ifdef AAC_DETAILED_STATUS_INFO | 141 | #ifdef AAC_DETAILED_STATUS_INFO |
140 | static char *aac_get_status_string(u32 status); | 142 | static char *aac_get_status_string(u32 status); |
@@ -152,10 +154,14 @@ int aac_commit = -1; | |||
152 | int startup_timeout = 180; | 154 | int startup_timeout = 180; |
153 | int aif_timeout = 120; | 155 | int aif_timeout = 120; |
154 | int aac_sync_mode; /* Only Sync. transfer - disabled */ | 156 | int aac_sync_mode; /* Only Sync. transfer - disabled */ |
157 | int aac_convert_sgl = 1; /* convert non-conformable s/g list - enabled */ | ||
155 | 158 | ||
156 | module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR); | 159 | module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR); |
157 | MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode" | 160 | MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode" |
158 | " 0=off, 1=on"); | 161 | " 0=off, 1=on"); |
162 | module_param(aac_convert_sgl, int, S_IRUGO|S_IWUSR); | ||
163 | MODULE_PARM_DESC(aac_convert_sgl, "Convert non-conformable s/g list" | ||
164 | " 0=off, 1=on"); | ||
159 | module_param(nondasd, int, S_IRUGO|S_IWUSR); | 165 | module_param(nondasd, int, S_IRUGO|S_IWUSR); |
160 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices." | 166 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices." |
161 | " 0=off, 1=on"); | 167 | " 0=off, 1=on"); |
@@ -963,25 +969,44 @@ static void io_callback(void *context, struct fib * fibptr); | |||
963 | 969 | ||
964 | static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) | 970 | static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count) |
965 | { | 971 | { |
966 | u16 fibsize; | 972 | struct aac_dev *dev = fib->dev; |
967 | struct aac_raw_io *readcmd; | 973 | u16 fibsize, command; |
974 | |||
968 | aac_fib_init(fib); | 975 | aac_fib_init(fib); |
969 | readcmd = (struct aac_raw_io *) fib_data(fib); | 976 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) { |
970 | readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | 977 | struct aac_raw_io2 *readcmd2; |
971 | readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | 978 | readcmd2 = (struct aac_raw_io2 *) fib_data(fib); |
972 | readcmd->count = cpu_to_le32(count<<9); | 979 | memset(readcmd2, 0, sizeof(struct aac_raw_io2)); |
973 | readcmd->cid = cpu_to_le16(scmd_id(cmd)); | 980 | readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff)); |
974 | readcmd->flags = cpu_to_le16(IO_TYPE_READ); | 981 | readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); |
975 | readcmd->bpTotal = 0; | 982 | readcmd2->byteCount = cpu_to_le32(count<<9); |
976 | readcmd->bpComplete = 0; | 983 | readcmd2->cid = cpu_to_le16(scmd_id(cmd)); |
984 | readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ); | ||
985 | aac_build_sgraw2(cmd, readcmd2, dev->scsi_host_ptr->sg_tablesize); | ||
986 | command = ContainerRawIo2; | ||
987 | fibsize = sizeof(struct aac_raw_io2) + | ||
988 | ((le32_to_cpu(readcmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212)); | ||
989 | } else { | ||
990 | struct aac_raw_io *readcmd; | ||
991 | readcmd = (struct aac_raw_io *) fib_data(fib); | ||
992 | readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
993 | readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
994 | readcmd->count = cpu_to_le32(count<<9); | ||
995 | readcmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
996 | readcmd->flags = cpu_to_le16(RIO_TYPE_READ); | ||
997 | readcmd->bpTotal = 0; | ||
998 | readcmd->bpComplete = 0; | ||
999 | aac_build_sgraw(cmd, &readcmd->sg); | ||
1000 | command = ContainerRawIo; | ||
1001 | fibsize = sizeof(struct aac_raw_io) + | ||
1002 | ((le32_to_cpu(readcmd->sg.count)-1) * sizeof(struct sgentryraw)); | ||
1003 | } | ||
977 | 1004 | ||
978 | aac_build_sgraw(cmd, &readcmd->sg); | ||
979 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw)); | ||
980 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); | 1005 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); |
981 | /* | 1006 | /* |
982 | * Now send the Fib to the adapter | 1007 | * Now send the Fib to the adapter |
983 | */ | 1008 | */ |
984 | return aac_fib_send(ContainerRawIo, | 1009 | return aac_fib_send(command, |
985 | fib, | 1010 | fib, |
986 | fibsize, | 1011 | fibsize, |
987 | FsaNormal, | 1012 | FsaNormal, |
@@ -1052,28 +1077,50 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 | |||
1052 | 1077 | ||
1053 | static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua) | 1078 | static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua) |
1054 | { | 1079 | { |
1055 | u16 fibsize; | 1080 | struct aac_dev *dev = fib->dev; |
1056 | struct aac_raw_io *writecmd; | 1081 | u16 fibsize, command; |
1082 | |||
1057 | aac_fib_init(fib); | 1083 | aac_fib_init(fib); |
1058 | writecmd = (struct aac_raw_io *) fib_data(fib); | 1084 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) { |
1059 | writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | 1085 | struct aac_raw_io2 *writecmd2; |
1060 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | 1086 | writecmd2 = (struct aac_raw_io2 *) fib_data(fib); |
1061 | writecmd->count = cpu_to_le32(count<<9); | 1087 | memset(writecmd2, 0, sizeof(struct aac_raw_io2)); |
1062 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | 1088 | writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff)); |
1063 | writecmd->flags = (fua && ((aac_cache & 5) != 1) && | 1089 | writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); |
1064 | (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ? | 1090 | writecmd2->byteCount = cpu_to_le32(count<<9); |
1065 | cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) : | 1091 | writecmd2->cid = cpu_to_le16(scmd_id(cmd)); |
1066 | cpu_to_le16(IO_TYPE_WRITE); | 1092 | writecmd2->flags = (fua && ((aac_cache & 5) != 1) && |
1067 | writecmd->bpTotal = 0; | 1093 | (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ? |
1068 | writecmd->bpComplete = 0; | 1094 | cpu_to_le16(RIO2_IO_TYPE_WRITE|RIO2_IO_SUREWRITE) : |
1069 | 1095 | cpu_to_le16(RIO2_IO_TYPE_WRITE); | |
1070 | aac_build_sgraw(cmd, &writecmd->sg); | 1096 | aac_build_sgraw2(cmd, writecmd2, dev->scsi_host_ptr->sg_tablesize); |
1071 | fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw)); | 1097 | command = ContainerRawIo2; |
1098 | fibsize = sizeof(struct aac_raw_io2) + | ||
1099 | ((le32_to_cpu(writecmd2->sgeCnt)-1) * sizeof(struct sge_ieee1212)); | ||
1100 | } else { | ||
1101 | struct aac_raw_io *writecmd; | ||
1102 | writecmd = (struct aac_raw_io *) fib_data(fib); | ||
1103 | writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff)); | ||
1104 | writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32)); | ||
1105 | writecmd->count = cpu_to_le32(count<<9); | ||
1106 | writecmd->cid = cpu_to_le16(scmd_id(cmd)); | ||
1107 | writecmd->flags = (fua && ((aac_cache & 5) != 1) && | ||
1108 | (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ? | ||
1109 | cpu_to_le16(RIO_TYPE_WRITE|RIO_SUREWRITE) : | ||
1110 | cpu_to_le16(RIO_TYPE_WRITE); | ||
1111 | writecmd->bpTotal = 0; | ||
1112 | writecmd->bpComplete = 0; | ||
1113 | aac_build_sgraw(cmd, &writecmd->sg); | ||
1114 | command = ContainerRawIo; | ||
1115 | fibsize = sizeof(struct aac_raw_io) + | ||
1116 | ((le32_to_cpu(writecmd->sg.count)-1) * sizeof (struct sgentryraw)); | ||
1117 | } | ||
1118 | |||
1072 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); | 1119 | BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr))); |
1073 | /* | 1120 | /* |
1074 | * Now send the Fib to the adapter | 1121 | * Now send the Fib to the adapter |
1075 | */ | 1122 | */ |
1076 | return aac_fib_send(ContainerRawIo, | 1123 | return aac_fib_send(command, |
1077 | fib, | 1124 | fib, |
1078 | fibsize, | 1125 | fibsize, |
1079 | FsaNormal, | 1126 | FsaNormal, |
@@ -1492,8 +1539,6 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1492 | dev->a_ops.adapter_write = aac_write_block; | 1539 | dev->a_ops.adapter_write = aac_write_block; |
1493 | } | 1540 | } |
1494 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; | 1541 | dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT; |
1495 | if (dev->adapter_info.options & AAC_OPT_NEW_COMM_TYPE1) | ||
1496 | dev->adapter_info.options |= AAC_OPT_NEW_COMM; | ||
1497 | if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { | 1542 | if (!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) { |
1498 | /* | 1543 | /* |
1499 | * Worst case size that could cause sg overflow when | 1544 | * Worst case size that could cause sg overflow when |
@@ -2616,12 +2661,18 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
2616 | srbreply = (struct aac_srb_reply *) fib_data(fibptr); | 2661 | srbreply = (struct aac_srb_reply *) fib_data(fibptr); |
2617 | 2662 | ||
2618 | scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */ | 2663 | scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */ |
2619 | /* | ||
2620 | * Calculate resid for sg | ||
2621 | */ | ||
2622 | 2664 | ||
2623 | scsi_set_resid(scsicmd, scsi_bufflen(scsicmd) | 2665 | if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) { |
2624 | - le32_to_cpu(srbreply->data_xfer_length)); | 2666 | /* fast response */ |
2667 | srbreply->srb_status = cpu_to_le32(SRB_STATUS_SUCCESS); | ||
2668 | srbreply->scsi_status = cpu_to_le32(SAM_STAT_GOOD); | ||
2669 | } else { | ||
2670 | /* | ||
2671 | * Calculate resid for sg | ||
2672 | */ | ||
2673 | scsi_set_resid(scsicmd, scsi_bufflen(scsicmd) | ||
2674 | - le32_to_cpu(srbreply->data_xfer_length)); | ||
2675 | } | ||
2625 | 2676 | ||
2626 | scsi_dma_unmap(scsicmd); | 2677 | scsi_dma_unmap(scsicmd); |
2627 | 2678 | ||
@@ -2954,6 +3005,118 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* | |||
2954 | return byte_count; | 3005 | return byte_count; |
2955 | } | 3006 | } |
2956 | 3007 | ||
3008 | static unsigned long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max) | ||
3009 | { | ||
3010 | unsigned long byte_count = 0; | ||
3011 | int nseg; | ||
3012 | |||
3013 | nseg = scsi_dma_map(scsicmd); | ||
3014 | BUG_ON(nseg < 0); | ||
3015 | if (nseg) { | ||
3016 | struct scatterlist *sg; | ||
3017 | int i, conformable = 0; | ||
3018 | u32 min_size = PAGE_SIZE, cur_size; | ||
3019 | |||
3020 | scsi_for_each_sg(scsicmd, sg, nseg, i) { | ||
3021 | int count = sg_dma_len(sg); | ||
3022 | u64 addr = sg_dma_address(sg); | ||
3023 | |||
3024 | BUG_ON(i >= sg_max); | ||
3025 | rio2->sge[i].addrHigh = cpu_to_le32((u32)(addr>>32)); | ||
3026 | rio2->sge[i].addrLow = cpu_to_le32((u32)(addr & 0xffffffff)); | ||
3027 | cur_size = cpu_to_le32(count); | ||
3028 | rio2->sge[i].length = cur_size; | ||
3029 | rio2->sge[i].flags = 0; | ||
3030 | if (i == 0) { | ||
3031 | conformable = 1; | ||
3032 | rio2->sgeFirstSize = cur_size; | ||
3033 | } else if (i == 1) { | ||
3034 | rio2->sgeNominalSize = cur_size; | ||
3035 | min_size = cur_size; | ||
3036 | } else if ((i+1) < nseg && cur_size != rio2->sgeNominalSize) { | ||
3037 | conformable = 0; | ||
3038 | if (cur_size < min_size) | ||
3039 | min_size = cur_size; | ||
3040 | } | ||
3041 | byte_count += count; | ||
3042 | } | ||
3043 | |||
3044 | /* hba wants the size to be exact */ | ||
3045 | if (byte_count > scsi_bufflen(scsicmd)) { | ||
3046 | u32 temp = le32_to_cpu(rio2->sge[i-1].length) - | ||
3047 | (byte_count - scsi_bufflen(scsicmd)); | ||
3048 | rio2->sge[i-1].length = cpu_to_le32(temp); | ||
3049 | byte_count = scsi_bufflen(scsicmd); | ||
3050 | } | ||
3051 | |||
3052 | rio2->sgeCnt = cpu_to_le32(nseg); | ||
3053 | rio2->flags |= cpu_to_le16(RIO2_SG_FORMAT_IEEE1212); | ||
3054 | /* not conformable: evaluate required sg elements */ | ||
3055 | if (!conformable) { | ||
3056 | int j, nseg_new = nseg, err_found; | ||
3057 | for (i = min_size / PAGE_SIZE; i >= 1; --i) { | ||
3058 | err_found = 0; | ||
3059 | nseg_new = 2; | ||
3060 | for (j = 1; j < nseg - 1; ++j) { | ||
3061 | if (rio2->sge[j].length % (i*PAGE_SIZE)) { | ||
3062 | err_found = 1; | ||
3063 | break; | ||
3064 | } | ||
3065 | nseg_new += (rio2->sge[j].length / (i*PAGE_SIZE)); | ||
3066 | } | ||
3067 | if (!err_found) | ||
3068 | break; | ||
3069 | } | ||
3070 | if (i > 0 && nseg_new <= sg_max) | ||
3071 | aac_convert_sgraw2(rio2, i, nseg, nseg_new); | ||
3072 | } else | ||
3073 | rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT); | ||
3074 | |||
3075 | /* Check for command underflow */ | ||
3076 | if (scsicmd->underflow && (byte_count < scsicmd->underflow)) { | ||
3077 | printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n", | ||
3078 | byte_count, scsicmd->underflow); | ||
3079 | } | ||
3080 | } | ||
3081 | |||
3082 | return byte_count; | ||
3083 | } | ||
3084 | |||
3085 | static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new) | ||
3086 | { | ||
3087 | struct sge_ieee1212 *sge; | ||
3088 | int i, j, pos; | ||
3089 | u32 addr_low; | ||
3090 | |||
3091 | if (aac_convert_sgl == 0) | ||
3092 | return 0; | ||
3093 | |||
3094 | sge = kmalloc(nseg_new * sizeof(struct sge_ieee1212), GFP_ATOMIC); | ||
3095 | if (sge == NULL) | ||
3096 | return -1; | ||
3097 | |||
3098 | for (i = 1, pos = 1; i < nseg-1; ++i) { | ||
3099 | for (j = 0; j < rio2->sge[i].length / (pages * PAGE_SIZE); ++j) { | ||
3100 | addr_low = rio2->sge[i].addrLow + j * pages * PAGE_SIZE; | ||
3101 | sge[pos].addrLow = addr_low; | ||
3102 | sge[pos].addrHigh = rio2->sge[i].addrHigh; | ||
3103 | if (addr_low < rio2->sge[i].addrLow) | ||
3104 | sge[pos].addrHigh++; | ||
3105 | sge[pos].length = pages * PAGE_SIZE; | ||
3106 | sge[pos].flags = 0; | ||
3107 | pos++; | ||
3108 | } | ||
3109 | } | ||
3110 | sge[pos] = rio2->sge[nseg-1]; | ||
3111 | memcpy(&rio2->sge[1], &sge[1], (nseg_new-1)*sizeof(struct sge_ieee1212)); | ||
3112 | |||
3113 | kfree(sge); | ||
3114 | rio2->sgeCnt = cpu_to_le32(nseg_new); | ||
3115 | rio2->flags |= cpu_to_le16(RIO2_SGL_CONFORMANT); | ||
3116 | rio2->sgeNominalSize = pages * PAGE_SIZE; | ||
3117 | return 0; | ||
3118 | } | ||
3119 | |||
2957 | #ifdef AAC_DETAILED_STATUS_INFO | 3120 | #ifdef AAC_DETAILED_STATUS_INFO |
2958 | 3121 | ||
2959 | struct aac_srb_status_info { | 3122 | struct aac_srb_status_info { |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6ab32db73bb6..9e933a88a8bc 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -12,7 +12,7 @@ | |||
12 | *----------------------------------------------------------------------------*/ | 12 | *----------------------------------------------------------------------------*/ |
13 | 13 | ||
14 | #ifndef AAC_DRIVER_BUILD | 14 | #ifndef AAC_DRIVER_BUILD |
15 | # define AAC_DRIVER_BUILD 28900 | 15 | # define AAC_DRIVER_BUILD 29800 |
16 | # define AAC_DRIVER_BRANCH "-ms" | 16 | # define AAC_DRIVER_BRANCH "-ms" |
17 | #endif | 17 | #endif |
18 | #define MAXIMUM_NUM_CONTAINERS 32 | 18 | #define MAXIMUM_NUM_CONTAINERS 32 |
@@ -100,6 +100,13 @@ struct user_sgentryraw { | |||
100 | u32 flags; /* reserved for F/W use */ | 100 | u32 flags; /* reserved for F/W use */ |
101 | }; | 101 | }; |
102 | 102 | ||
103 | struct sge_ieee1212 { | ||
104 | u32 addrLow; | ||
105 | u32 addrHigh; | ||
106 | u32 length; | ||
107 | u32 flags; | ||
108 | }; | ||
109 | |||
103 | /* | 110 | /* |
104 | * SGMAP | 111 | * SGMAP |
105 | * | 112 | * |
@@ -270,6 +277,8 @@ enum aac_queue_types { | |||
270 | */ | 277 | */ |
271 | 278 | ||
272 | #define FIB_MAGIC 0x0001 | 279 | #define FIB_MAGIC 0x0001 |
280 | #define FIB_MAGIC2 0x0004 | ||
281 | #define FIB_MAGIC2_64 0x0005 | ||
273 | 282 | ||
274 | /* | 283 | /* |
275 | * Define the priority levels the FSA communication routines support. | 284 | * Define the priority levels the FSA communication routines support. |
@@ -296,22 +305,20 @@ struct aac_fibhdr { | |||
296 | __le32 XferState; /* Current transfer state for this CCB */ | 305 | __le32 XferState; /* Current transfer state for this CCB */ |
297 | __le16 Command; /* Routing information for the destination */ | 306 | __le16 Command; /* Routing information for the destination */ |
298 | u8 StructType; /* Type FIB */ | 307 | u8 StructType; /* Type FIB */ |
299 | u8 Flags; /* Flags for FIB */ | 308 | u8 Unused; /* Unused */ |
300 | __le16 Size; /* Size of this FIB in bytes */ | 309 | __le16 Size; /* Size of this FIB in bytes */ |
301 | __le16 SenderSize; /* Size of the FIB in the sender | 310 | __le16 SenderSize; /* Size of the FIB in the sender |
302 | (for response sizing) */ | 311 | (for response sizing) */ |
303 | __le32 SenderFibAddress; /* Host defined data in the FIB */ | 312 | __le32 SenderFibAddress; /* Host defined data in the FIB */ |
304 | __le32 ReceiverFibAddress;/* Logical address of this FIB for | ||
305 | the adapter */ | ||
306 | u32 SenderData; /* Place holder for the sender to store data */ | ||
307 | union { | 313 | union { |
308 | struct { | 314 | __le32 ReceiverFibAddress;/* Logical address of this FIB for |
309 | __le32 _ReceiverTimeStart; /* Timestamp for | 315 | the adapter (old) */ |
310 | receipt of fib */ | 316 | __le32 SenderFibAddressHigh;/* upper 32bit of phys. FIB address */ |
311 | __le32 _ReceiverTimeDone; /* Timestamp for | 317 | __le32 TimeStamp; /* otherwise timestamp for FW internal use */ |
312 | completion of fib */ | 318 | } u; |
313 | } _s; | 319 | u32 Handle; /* FIB handle used for MSGU commnunication */ |
314 | } _u; | 320 | u32 Previous; /* FW internal use */ |
321 | u32 Next; /* FW internal use */ | ||
315 | }; | 322 | }; |
316 | 323 | ||
317 | struct hw_fib { | 324 | struct hw_fib { |
@@ -361,6 +368,7 @@ struct hw_fib { | |||
361 | #define ContainerCommand 500 | 368 | #define ContainerCommand 500 |
362 | #define ContainerCommand64 501 | 369 | #define ContainerCommand64 501 |
363 | #define ContainerRawIo 502 | 370 | #define ContainerRawIo 502 |
371 | #define ContainerRawIo2 503 | ||
364 | /* | 372 | /* |
365 | * Scsi Port commands (scsi passthrough) | 373 | * Scsi Port commands (scsi passthrough) |
366 | */ | 374 | */ |
@@ -417,6 +425,7 @@ enum fib_xfer_state { | |||
417 | #define ADAPTER_INIT_STRUCT_REVISION 3 | 425 | #define ADAPTER_INIT_STRUCT_REVISION 3 |
418 | #define ADAPTER_INIT_STRUCT_REVISION_4 4 // rocket science | 426 | #define ADAPTER_INIT_STRUCT_REVISION_4 4 // rocket science |
419 | #define ADAPTER_INIT_STRUCT_REVISION_6 6 /* PMC src */ | 427 | #define ADAPTER_INIT_STRUCT_REVISION_6 6 /* PMC src */ |
428 | #define ADAPTER_INIT_STRUCT_REVISION_7 7 /* Denali */ | ||
420 | 429 | ||
421 | struct aac_init | 430 | struct aac_init |
422 | { | 431 | { |
@@ -441,7 +450,9 @@ struct aac_init | |||
441 | #define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001 | 450 | #define INITFLAGS_NEW_COMM_SUPPORTED 0x00000001 |
442 | #define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010 | 451 | #define INITFLAGS_DRIVER_USES_UTC_TIME 0x00000010 |
443 | #define INITFLAGS_DRIVER_SUPPORTS_PM 0x00000020 | 452 | #define INITFLAGS_DRIVER_SUPPORTS_PM 0x00000020 |
444 | #define INITFLAGS_NEW_COMM_TYPE1_SUPPORTED 0x00000041 | 453 | #define INITFLAGS_NEW_COMM_TYPE1_SUPPORTED 0x00000040 |
454 | #define INITFLAGS_FAST_JBOD_SUPPORTED 0x00000080 | ||
455 | #define INITFLAGS_NEW_COMM_TYPE2_SUPPORTED 0x00000100 | ||
445 | __le32 MaxIoCommands; /* max outstanding commands */ | 456 | __le32 MaxIoCommands; /* max outstanding commands */ |
446 | __le32 MaxIoSize; /* largest I/O command */ | 457 | __le32 MaxIoSize; /* largest I/O command */ |
447 | __le32 MaxFibSize; /* largest FIB to adapter */ | 458 | __le32 MaxFibSize; /* largest FIB to adapter */ |
@@ -1124,6 +1135,7 @@ struct aac_dev | |||
1124 | # define AAC_COMM_PRODUCER 0 | 1135 | # define AAC_COMM_PRODUCER 0 |
1125 | # define AAC_COMM_MESSAGE 1 | 1136 | # define AAC_COMM_MESSAGE 1 |
1126 | # define AAC_COMM_MESSAGE_TYPE1 3 | 1137 | # define AAC_COMM_MESSAGE_TYPE1 3 |
1138 | # define AAC_COMM_MESSAGE_TYPE2 4 | ||
1127 | u8 raw_io_interface; | 1139 | u8 raw_io_interface; |
1128 | u8 raw_io_64; | 1140 | u8 raw_io_64; |
1129 | u8 printf_enabled; | 1141 | u8 printf_enabled; |
@@ -1182,6 +1194,7 @@ struct aac_dev | |||
1182 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) | 1194 | #define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001) |
1183 | #define FIB_CONTEXT_FLAG (0x00000002) | 1195 | #define FIB_CONTEXT_FLAG (0x00000002) |
1184 | #define FIB_CONTEXT_FLAG_WAIT (0x00000004) | 1196 | #define FIB_CONTEXT_FLAG_WAIT (0x00000004) |
1197 | #define FIB_CONTEXT_FLAG_FASTRESP (0x00000008) | ||
1185 | 1198 | ||
1186 | /* | 1199 | /* |
1187 | * Define the command values | 1200 | * Define the command values |
@@ -1288,6 +1301,22 @@ struct aac_dev | |||
1288 | #define CMDATA_SYNCH 4 | 1301 | #define CMDATA_SYNCH 4 |
1289 | #define CMUNSTABLE 5 | 1302 | #define CMUNSTABLE 5 |
1290 | 1303 | ||
1304 | #define RIO_TYPE_WRITE 0x0000 | ||
1305 | #define RIO_TYPE_READ 0x0001 | ||
1306 | #define RIO_SUREWRITE 0x0008 | ||
1307 | |||
1308 | #define RIO2_IO_TYPE 0x0003 | ||
1309 | #define RIO2_IO_TYPE_WRITE 0x0000 | ||
1310 | #define RIO2_IO_TYPE_READ 0x0001 | ||
1311 | #define RIO2_IO_TYPE_VERIFY 0x0002 | ||
1312 | #define RIO2_IO_ERROR 0x0004 | ||
1313 | #define RIO2_IO_SUREWRITE 0x0008 | ||
1314 | #define RIO2_SGL_CONFORMANT 0x0010 | ||
1315 | #define RIO2_SG_FORMAT 0xF000 | ||
1316 | #define RIO2_SG_FORMAT_ARC 0x0000 | ||
1317 | #define RIO2_SG_FORMAT_SRL 0x1000 | ||
1318 | #define RIO2_SG_FORMAT_IEEE1212 0x2000 | ||
1319 | |||
1291 | struct aac_read | 1320 | struct aac_read |
1292 | { | 1321 | { |
1293 | __le32 command; | 1322 | __le32 command; |
@@ -1332,9 +1361,6 @@ struct aac_write64 | |||
1332 | __le32 block; | 1361 | __le32 block; |
1333 | __le16 pad; | 1362 | __le16 pad; |
1334 | __le16 flags; | 1363 | __le16 flags; |
1335 | #define IO_TYPE_WRITE 0x00000000 | ||
1336 | #define IO_TYPE_READ 0x00000001 | ||
1337 | #define IO_SUREWRITE 0x00000008 | ||
1338 | struct sgmap64 sg; // Must be last in struct because it is variable | 1364 | struct sgmap64 sg; // Must be last in struct because it is variable |
1339 | }; | 1365 | }; |
1340 | struct aac_write_reply | 1366 | struct aac_write_reply |
@@ -1355,6 +1381,22 @@ struct aac_raw_io | |||
1355 | struct sgmapraw sg; | 1381 | struct sgmapraw sg; |
1356 | }; | 1382 | }; |
1357 | 1383 | ||
1384 | struct aac_raw_io2 { | ||
1385 | __le32 blockLow; | ||
1386 | __le32 blockHigh; | ||
1387 | __le32 byteCount; | ||
1388 | __le16 cid; | ||
1389 | __le16 flags; /* RIO2 flags */ | ||
1390 | __le32 sgeFirstSize; /* size of first sge el. */ | ||
1391 | __le32 sgeNominalSize; /* size of 2nd sge el. (if conformant) */ | ||
1392 | u8 sgeCnt; /* only 8 bits required */ | ||
1393 | u8 bpTotal; /* reserved for F/W use */ | ||
1394 | u8 bpComplete; /* reserved for F/W use */ | ||
1395 | u8 sgeFirstIndex; /* reserved for F/W use */ | ||
1396 | u8 unused[4]; | ||
1397 | struct sge_ieee1212 sge[1]; | ||
1398 | }; | ||
1399 | |||
1358 | #define CT_FLUSH_CACHE 129 | 1400 | #define CT_FLUSH_CACHE 129 |
1359 | struct aac_synchronize { | 1401 | struct aac_synchronize { |
1360 | __le32 command; /* VM_ContainerConfig */ | 1402 | __le32 command; /* VM_ContainerConfig */ |
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 0bd38da4ada0..1ef041bc60c8 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
@@ -498,6 +498,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
498 | return -ENOMEM; | 498 | return -ENOMEM; |
499 | } | 499 | } |
500 | aac_fib_init(srbfib); | 500 | aac_fib_init(srbfib); |
501 | /* raw_srb FIB is not FastResponseCapable */ | ||
502 | srbfib->hw_fib_va->header.XferState &= ~cpu_to_le32(FastResponseCapable); | ||
501 | 503 | ||
502 | srbcmd = (struct aac_srb*) fib_data(srbfib); | 504 | srbcmd = (struct aac_srb*) fib_data(srbfib); |
503 | 505 | ||
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 8e4b525b1b79..8e5d3be16127 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -58,7 +58,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
58 | dma_addr_t phys; | 58 | dma_addr_t phys; |
59 | unsigned long aac_max_hostphysmempages; | 59 | unsigned long aac_max_hostphysmempages; |
60 | 60 | ||
61 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) | 61 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 || |
62 | dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) | ||
62 | host_rrq_size = (dev->scsi_host_ptr->can_queue | 63 | host_rrq_size = (dev->scsi_host_ptr->can_queue |
63 | + AAC_NUM_MGT_FIB) * sizeof(u32); | 64 | + AAC_NUM_MGT_FIB) * sizeof(u32); |
64 | size = fibsize + sizeof(struct aac_init) + commsize + | 65 | size = fibsize + sizeof(struct aac_init) + commsize + |
@@ -75,7 +76,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
75 | dev->comm_phys = phys; | 76 | dev->comm_phys = phys; |
76 | dev->comm_size = size; | 77 | dev->comm_size = size; |
77 | 78 | ||
78 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { | 79 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 || |
80 | dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { | ||
79 | dev->host_rrq = (u32 *)(base + fibsize); | 81 | dev->host_rrq = (u32 *)(base + fibsize); |
80 | dev->host_rrq_pa = phys + fibsize; | 82 | dev->host_rrq_pa = phys + fibsize; |
81 | memset(dev->host_rrq, 0, host_rrq_size); | 83 | memset(dev->host_rrq, 0, host_rrq_size); |
@@ -115,26 +117,32 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
115 | else | 117 | else |
116 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | 118 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
117 | 119 | ||
118 | init->InitFlags = 0; | 120 | init->InitFlags = cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME | |
121 | INITFLAGS_DRIVER_SUPPORTS_PM); | ||
122 | init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | ||
123 | init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); | ||
124 | init->MaxFibSize = cpu_to_le32(dev->max_fib_size); | ||
125 | init->MaxNumAif = cpu_to_le32(dev->max_num_aif); | ||
126 | |||
119 | if (dev->comm_interface == AAC_COMM_MESSAGE) { | 127 | if (dev->comm_interface == AAC_COMM_MESSAGE) { |
120 | init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); | 128 | init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED); |
121 | dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); | 129 | dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n")); |
122 | } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { | 130 | } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { |
123 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6); | 131 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6); |
124 | init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_TYPE1_SUPPORTED); | 132 | init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED | |
125 | dprintk((KERN_WARNING | 133 | INITFLAGS_NEW_COMM_TYPE1_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED); |
126 | "aacraid: New Comm Interface type1 enabled\n")); | 134 | init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32)); |
135 | init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff)); | ||
136 | dprintk((KERN_WARNING"aacraid: New Comm Interface type1 enabled\n")); | ||
137 | } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { | ||
138 | init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7); | ||
139 | init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED | | ||
140 | INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED); | ||
141 | init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32)); | ||
142 | init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff)); | ||
143 | init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */ | ||
144 | dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n")); | ||
127 | } | 145 | } |
128 | init->InitFlags |= cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME | | ||
129 | INITFLAGS_DRIVER_SUPPORTS_PM); | ||
130 | init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | ||
131 | init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9); | ||
132 | init->MaxFibSize = cpu_to_le32(dev->max_fib_size); | ||
133 | |||
134 | init->MaxNumAif = cpu_to_le32(dev->max_num_aif); | ||
135 | init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32)); | ||
136 | init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff)); | ||
137 | |||
138 | 146 | ||
139 | /* | 147 | /* |
140 | * Increment the base address by the amount already used | 148 | * Increment the base address by the amount already used |
@@ -354,13 +362,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
354 | if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) { | 362 | if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) { |
355 | /* driver supports TYPE1 (Tupelo) */ | 363 | /* driver supports TYPE1 (Tupelo) */ |
356 | dev->comm_interface = AAC_COMM_MESSAGE_TYPE1; | 364 | dev->comm_interface = AAC_COMM_MESSAGE_TYPE1; |
365 | } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) { | ||
366 | /* driver supports TYPE2 (Denali) */ | ||
367 | dev->comm_interface = AAC_COMM_MESSAGE_TYPE2; | ||
357 | } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4)) || | 368 | } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4)) || |
358 | (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3)) || | 369 | (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3))) { |
359 | (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) { | 370 | /* driver doesn't TYPE3 and TYPE4 */ |
360 | /* driver doesn't support TYPE2 (Series7), TYPE3 and TYPE4 */ | 371 | /* switch to sync. mode */ |
361 | /* switch to sync. mode */ | 372 | dev->comm_interface = AAC_COMM_MESSAGE_TYPE2; |
362 | dev->comm_interface = AAC_COMM_MESSAGE_TYPE1; | 373 | dev->sync_mode = 1; |
363 | dev->sync_mode = 1; | ||
364 | } | 374 | } |
365 | } | 375 | } |
366 | if ((dev->comm_interface == AAC_COMM_MESSAGE) && | 376 | if ((dev->comm_interface == AAC_COMM_MESSAGE) && |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 906a5013edae..1be0776a80c4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -136,6 +136,7 @@ int aac_fib_setup(struct aac_dev * dev) | |||
136 | i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); | 136 | i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); |
137 | i++, fibptr++) | 137 | i++, fibptr++) |
138 | { | 138 | { |
139 | fibptr->flags = 0; | ||
139 | fibptr->dev = dev; | 140 | fibptr->dev = dev; |
140 | fibptr->hw_fib_va = hw_fib; | 141 | fibptr->hw_fib_va = hw_fib; |
141 | fibptr->data = (void *) fibptr->hw_fib_va->data; | 142 | fibptr->data = (void *) fibptr->hw_fib_va->data; |
@@ -240,11 +241,11 @@ void aac_fib_init(struct fib *fibptr) | |||
240 | { | 241 | { |
241 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 242 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
242 | 243 | ||
244 | memset(&hw_fib->header, 0, sizeof(struct aac_fibhdr)); | ||
243 | hw_fib->header.StructType = FIB_MAGIC; | 245 | hw_fib->header.StructType = FIB_MAGIC; |
244 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); | 246 | hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); |
245 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); | 247 | hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); |
246 | hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */ | 248 | hw_fib->header.u.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); |
247 | hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); | ||
248 | hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); | 249 | hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size); |
249 | } | 250 | } |
250 | 251 | ||
@@ -259,7 +260,6 @@ void aac_fib_init(struct fib *fibptr) | |||
259 | static void fib_dealloc(struct fib * fibptr) | 260 | static void fib_dealloc(struct fib * fibptr) |
260 | { | 261 | { |
261 | struct hw_fib *hw_fib = fibptr->hw_fib_va; | 262 | struct hw_fib *hw_fib = fibptr->hw_fib_va; |
262 | BUG_ON(hw_fib->header.StructType != FIB_MAGIC); | ||
263 | hw_fib->header.XferState = 0; | 263 | hw_fib->header.XferState = 0; |
264 | } | 264 | } |
265 | 265 | ||
@@ -370,7 +370,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw | |||
370 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); | 370 | entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size)); |
371 | entry->addr = hw_fib->header.SenderFibAddress; | 371 | entry->addr = hw_fib->header.SenderFibAddress; |
372 | /* Restore adapters pointer to the FIB */ | 372 | /* Restore adapters pointer to the FIB */ |
373 | hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ | 373 | hw_fib->header.u.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */ |
374 | map = 0; | 374 | map = 0; |
375 | } | 375 | } |
376 | /* | 376 | /* |
@@ -450,7 +450,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
450 | */ | 450 | */ |
451 | 451 | ||
452 | hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); | 452 | hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); |
453 | hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); | 453 | hw_fib->header.Handle = (u32)(fibptr - dev->fibs) + 1; |
454 | /* | 454 | /* |
455 | * Set FIB state to indicate where it came from and if we want a | 455 | * Set FIB state to indicate where it came from and if we want a |
456 | * response from the adapter. Also load the command from the | 456 | * response from the adapter. Also load the command from the |
@@ -460,7 +460,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
460 | */ | 460 | */ |
461 | hw_fib->header.Command = cpu_to_le16(command); | 461 | hw_fib->header.Command = cpu_to_le16(command); |
462 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); | 462 | hw_fib->header.XferState |= cpu_to_le32(SentFromHost); |
463 | fibptr->hw_fib_va->header.Flags = 0; /* 0 the flags field - internal only*/ | ||
464 | /* | 463 | /* |
465 | * Set the size of the Fib we want to send to the adapter | 464 | * Set the size of the Fib we want to send to the adapter |
466 | */ | 465 | */ |
@@ -711,7 +710,8 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
711 | unsigned long nointr = 0; | 710 | unsigned long nointr = 0; |
712 | unsigned long qflags; | 711 | unsigned long qflags; |
713 | 712 | ||
714 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { | 713 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 || |
714 | dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { | ||
715 | kfree(hw_fib); | 715 | kfree(hw_fib); |
716 | return 0; | 716 | return 0; |
717 | } | 717 | } |
@@ -724,7 +724,9 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
724 | /* | 724 | /* |
725 | * If we plan to do anything check the structure type first. | 725 | * If we plan to do anything check the structure type first. |
726 | */ | 726 | */ |
727 | if (hw_fib->header.StructType != FIB_MAGIC) { | 727 | if (hw_fib->header.StructType != FIB_MAGIC && |
728 | hw_fib->header.StructType != FIB_MAGIC2 && | ||
729 | hw_fib->header.StructType != FIB_MAGIC2_64) { | ||
728 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 730 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
729 | kfree(hw_fib); | 731 | kfree(hw_fib); |
730 | return -EINVAL; | 732 | return -EINVAL; |
@@ -786,7 +788,9 @@ int aac_fib_complete(struct fib *fibptr) | |||
786 | * If we plan to do anything check the structure type first. | 788 | * If we plan to do anything check the structure type first. |
787 | */ | 789 | */ |
788 | 790 | ||
789 | if (hw_fib->header.StructType != FIB_MAGIC) | 791 | if (hw_fib->header.StructType != FIB_MAGIC && |
792 | hw_fib->header.StructType != FIB_MAGIC2 && | ||
793 | hw_fib->header.StructType != FIB_MAGIC2_64) | ||
790 | return -EINVAL; | 794 | return -EINVAL; |
791 | /* | 795 | /* |
792 | * This block completes a cdb which orginated on the host and we | 796 | * This block completes a cdb which orginated on the host and we |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index f0c66a80ad13..d81b2810f0f7 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
@@ -101,6 +101,7 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
101 | */ | 101 | */ |
102 | *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); | 102 | *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); |
103 | hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); | 103 | hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); |
104 | fib->flags |= FIB_CONTEXT_FLAG_FASTRESP; | ||
104 | } | 105 | } |
105 | 106 | ||
106 | FIB_COUNTER_INCREMENT(aac_config.FibRecved); | 107 | FIB_COUNTER_INCREMENT(aac_config.FibRecved); |
@@ -121,7 +122,7 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
121 | * NOTE: we cannot touch the fib after this | 122 | * NOTE: we cannot touch the fib after this |
122 | * call, because it may have been deallocated. | 123 | * call, because it may have been deallocated. |
123 | */ | 124 | */ |
124 | fib->flags = 0; | 125 | fib->flags &= FIB_CONTEXT_FLAG_FASTRESP; |
125 | fib->callback(fib->callback_data, fib); | 126 | fib->callback(fib->callback_data, fib); |
126 | } else { | 127 | } else { |
127 | unsigned long flagv; | 128 | unsigned long flagv; |
@@ -367,6 +368,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, | |||
367 | */ | 368 | */ |
368 | *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); | 369 | *(__le32 *)hwfib->data = cpu_to_le32(ST_OK); |
369 | hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); | 370 | hwfib->header.XferState |= cpu_to_le32(AdapterProcessed); |
371 | fib->flags |= FIB_CONTEXT_FLAG_FASTRESP; | ||
370 | } | 372 | } |
371 | 373 | ||
372 | FIB_COUNTER_INCREMENT(aac_config.FibRecved); | 374 | FIB_COUNTER_INCREMENT(aac_config.FibRecved); |
@@ -387,7 +389,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, | |||
387 | * NOTE: we cannot touch the fib after this | 389 | * NOTE: we cannot touch the fib after this |
388 | * call, because it may have been deallocated. | 390 | * call, because it may have been deallocated. |
389 | */ | 391 | */ |
390 | fib->flags = 0; | 392 | fib->flags &= FIB_CONTEXT_FLAG_FASTRESP; |
391 | fib->callback(fib->callback_data, fib); | 393 | fib->callback(fib->callback_data, fib); |
392 | } else { | 394 | } else { |
393 | unsigned long flagv; | 395 | unsigned long flagv; |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 2be612b0caa5..7199534cd07d 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -1166,7 +1166,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, | |||
1166 | aac->cardtype = index; | 1166 | aac->cardtype = index; |
1167 | INIT_LIST_HEAD(&aac->entry); | 1167 | INIT_LIST_HEAD(&aac->entry); |
1168 | 1168 | ||
1169 | aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); | 1169 | aac->fibs = kzalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL); |
1170 | if (!aac->fibs) | 1170 | if (!aac->fibs) |
1171 | goto out_free_host; | 1171 | goto out_free_host; |
1172 | spin_lock_init(&aac->fib_lock); | 1172 | spin_lock_init(&aac->fib_lock); |
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 0fb1f5507cd8..3b021ec63255 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
@@ -56,21 +56,10 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
56 | if (bellbits & PmDoorBellResponseSent) { | 56 | if (bellbits & PmDoorBellResponseSent) { |
57 | bellbits = PmDoorBellResponseSent; | 57 | bellbits = PmDoorBellResponseSent; |
58 | /* handle async. status */ | 58 | /* handle async. status */ |
59 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
60 | src_readl(dev, MUnit.ODR_C); | ||
59 | our_interrupt = 1; | 61 | our_interrupt = 1; |
60 | index = dev->host_rrq_idx; | 62 | index = dev->host_rrq_idx; |
61 | if (dev->host_rrq[index] == 0) { | ||
62 | u32 old_index = index; | ||
63 | /* adjust index */ | ||
64 | do { | ||
65 | index++; | ||
66 | if (index == dev->scsi_host_ptr->can_queue + | ||
67 | AAC_NUM_MGT_FIB) | ||
68 | index = 0; | ||
69 | if (dev->host_rrq[index] != 0) | ||
70 | break; | ||
71 | } while (index != old_index); | ||
72 | dev->host_rrq_idx = index; | ||
73 | } | ||
74 | for (;;) { | 63 | for (;;) { |
75 | isFastResponse = 0; | 64 | isFastResponse = 0; |
76 | /* remove toggle bit (31) */ | 65 | /* remove toggle bit (31) */ |
@@ -93,6 +82,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
93 | } else { | 82 | } else { |
94 | bellbits_shifted = (bellbits >> SRC_ODR_SHIFT); | 83 | bellbits_shifted = (bellbits >> SRC_ODR_SHIFT); |
95 | if (bellbits_shifted & DoorBellAifPending) { | 84 | if (bellbits_shifted & DoorBellAifPending) { |
85 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
86 | src_readl(dev, MUnit.ODR_C); | ||
96 | our_interrupt = 1; | 87 | our_interrupt = 1; |
97 | /* handle AIF */ | 88 | /* handle AIF */ |
98 | aac_intr_normal(dev, 0, 2, 0, NULL); | 89 | aac_intr_normal(dev, 0, 2, 0, NULL); |
@@ -100,6 +91,13 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
100 | unsigned long sflags; | 91 | unsigned long sflags; |
101 | struct list_head *entry; | 92 | struct list_head *entry; |
102 | int send_it = 0; | 93 | int send_it = 0; |
94 | extern int aac_sync_mode; | ||
95 | |||
96 | if (!aac_sync_mode) { | ||
97 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
98 | src_readl(dev, MUnit.ODR_C); | ||
99 | our_interrupt = 1; | ||
100 | } | ||
103 | 101 | ||
104 | if (dev->sync_fib) { | 102 | if (dev->sync_fib) { |
105 | our_interrupt = 1; | 103 | our_interrupt = 1; |
@@ -132,7 +130,6 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
132 | } | 130 | } |
133 | 131 | ||
134 | if (our_interrupt) { | 132 | if (our_interrupt) { |
135 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
136 | return IRQ_HANDLED; | 133 | return IRQ_HANDLED; |
137 | } | 134 | } |
138 | return IRQ_NONE; | 135 | return IRQ_NONE; |
@@ -336,6 +333,9 @@ static void aac_src_start_adapter(struct aac_dev *dev) | |||
336 | { | 333 | { |
337 | struct aac_init *init; | 334 | struct aac_init *init; |
338 | 335 | ||
336 | /* reset host_rrq_idx first */ | ||
337 | dev->host_rrq_idx = 0; | ||
338 | |||
339 | init = dev->init; | 339 | init = dev->init; |
340 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); | 340 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); |
341 | 341 | ||
@@ -397,31 +397,40 @@ static int aac_src_deliver_message(struct fib *fib) | |||
397 | q->numpending++; | 397 | q->numpending++; |
398 | spin_unlock_irqrestore(q->lock, qflags); | 398 | spin_unlock_irqrestore(q->lock, qflags); |
399 | 399 | ||
400 | /* Calculate the amount to the fibsize bits */ | 400 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { |
401 | fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; | 401 | /* Calculate the amount to the fibsize bits */ |
402 | if (fibsize > (ALIGN32 - 1)) | 402 | fibsize = (hdr_size + 127) / 128 - 1; |
403 | return -EMSGSIZE; | 403 | if (fibsize > (ALIGN32 - 1)) |
404 | return -EMSGSIZE; | ||
405 | /* New FIB header, 32-bit */ | ||
406 | address = fib->hw_fib_pa; | ||
407 | fib->hw_fib_va->header.StructType = FIB_MAGIC2; | ||
408 | fib->hw_fib_va->header.SenderFibAddress = (u32)address; | ||
409 | fib->hw_fib_va->header.u.TimeStamp = 0; | ||
410 | BUG_ON((u32)(address >> 32) != 0L); | ||
411 | address |= fibsize; | ||
412 | } else { | ||
413 | /* Calculate the amount to the fibsize bits */ | ||
414 | fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; | ||
415 | if (fibsize > (ALIGN32 - 1)) | ||
416 | return -EMSGSIZE; | ||
417 | |||
418 | /* Fill XPORT header */ | ||
419 | pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr); | ||
420 | pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.Handle); | ||
421 | pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa); | ||
422 | pFibX->Size = cpu_to_le32(hdr_size); | ||
404 | 423 | ||
405 | /* Fill XPORT header */ | 424 | /* |
406 | pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr); | 425 | * The xport header has been 32-byte aligned for us so that fibsize |
407 | /* | 426 | * can be masked out of this address by hardware. -- BenC |
408 | * This was stored by aac_fib_send() and it is the index into | 427 | */ |
409 | * dev->fibs. Not sure why we add 1 to it, but I suspect that it's | 428 | address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr); |
410 | * because it can't be zero when we pass it to the hardware. Note that | 429 | if (address & (ALIGN32 - 1)) |
411 | * it was stored in native endian, hence the lack of swapping. -- BenC | 430 | return -EINVAL; |
412 | */ | 431 | address |= fibsize; |
413 | pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.SenderData + 1); | 432 | } |
414 | pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa); | ||
415 | pFibX->Size = cpu_to_le32(hdr_size); | ||
416 | 433 | ||
417 | /* | ||
418 | * The xport header has been 32-byte aligned for us so that fibsize | ||
419 | * can be masked out of this address by hardware. -- BenC | ||
420 | */ | ||
421 | address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr); | ||
422 | if (address & (ALIGN32 - 1)) | ||
423 | return -EINVAL; | ||
424 | address |= fibsize; | ||
425 | src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff); | 434 | src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff); |
426 | src_writel(dev, MUnit.IQ_L, address & 0xffffffff); | 435 | src_writel(dev, MUnit.IQ_L, address & 0xffffffff); |
427 | 436 | ||
@@ -764,7 +773,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
764 | 773 | ||
765 | if (aac_init_adapter(dev) == NULL) | 774 | if (aac_init_adapter(dev) == NULL) |
766 | goto error_iounmap; | 775 | goto error_iounmap; |
767 | if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1) | 776 | if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) |
768 | goto error_iounmap; | 777 | goto error_iounmap; |
769 | dev->msi = aac_msi && !pci_enable_msi(dev->pdev); | 778 | dev->msi = aac_msi && !pci_enable_msi(dev->pdev); |
770 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, | 779 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, |