diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2010-01-12 16:02:47 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-01-18 17:51:05 -0500 |
commit | 9a069e196767d7b87184fd8d8211d22bb5b9c0b8 (patch) | |
tree | 44bc0f206793a2e9bcf280ea168e468bd62c15bb /drivers/scsi/qla2xxx/qla_iocb.c | |
parent | 90a86fc05ffefe48581c88106d0b9cc37f6e060c (diff) |
[SCSI] qla2xxx: Add BSG support for FC ELS/CT passthrough and vendor commands.
[jejb: fixed printk casting issues]
Signed-off-by: Sarang Radke <sarang.radke@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_iocb.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index c5ccac0bef76..8299a9891bfe 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1025,6 +1025,119 @@ qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx) | |||
1025 | /* Implicit: mbx->mbx10 = 0. */ | 1025 | /* Implicit: mbx->mbx10 = 0. */ |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | static void | ||
1029 | qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) | ||
1030 | { | ||
1031 | struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job; | ||
1032 | |||
1033 | els_iocb->entry_type = ELS_IOCB_TYPE; | ||
1034 | els_iocb->entry_count = 1; | ||
1035 | els_iocb->sys_define = 0; | ||
1036 | els_iocb->entry_status = 0; | ||
1037 | els_iocb->handle = sp->handle; | ||
1038 | els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); | ||
1039 | els_iocb->tx_dsd_count = __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt); | ||
1040 | els_iocb->vp_index = sp->fcport->vp_idx; | ||
1041 | els_iocb->sof_type = EST_SOFI3; | ||
1042 | els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt); | ||
1043 | |||
1044 | els_iocb->opcode =(((struct srb_bsg*)sp->ctx)->ctx.type == SRB_ELS_CMD_RPT) ? | ||
1045 | bsg_job->request->rqst_data.r_els.els_code : bsg_job->request->rqst_data.h_els.command_code; | ||
1046 | els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; | ||
1047 | els_iocb->port_id[1] = sp->fcport->d_id.b.area; | ||
1048 | els_iocb->port_id[2] = sp->fcport->d_id.b.domain; | ||
1049 | els_iocb->control_flags = 0; | ||
1050 | els_iocb->rx_byte_count = | ||
1051 | cpu_to_le32(bsg_job->reply_payload.payload_len); | ||
1052 | els_iocb->tx_byte_count = | ||
1053 | cpu_to_le32(bsg_job->request_payload.payload_len); | ||
1054 | |||
1055 | els_iocb->tx_address[0] = cpu_to_le32(LSD(sg_dma_address | ||
1056 | (bsg_job->request_payload.sg_list))); | ||
1057 | els_iocb->tx_address[1] = cpu_to_le32(MSD(sg_dma_address | ||
1058 | (bsg_job->request_payload.sg_list))); | ||
1059 | els_iocb->tx_len = cpu_to_le32(sg_dma_len | ||
1060 | (bsg_job->request_payload.sg_list)); | ||
1061 | |||
1062 | els_iocb->rx_address[0] = cpu_to_le32(LSD(sg_dma_address | ||
1063 | (bsg_job->reply_payload.sg_list))); | ||
1064 | els_iocb->rx_address[1] = cpu_to_le32(MSD(sg_dma_address | ||
1065 | (bsg_job->reply_payload.sg_list))); | ||
1066 | els_iocb->rx_len = cpu_to_le32(sg_dma_len | ||
1067 | (bsg_job->reply_payload.sg_list)); | ||
1068 | } | ||
1069 | |||
1070 | static void | ||
1071 | qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | ||
1072 | { | ||
1073 | uint16_t avail_dsds; | ||
1074 | uint32_t *cur_dsd; | ||
1075 | struct scatterlist *sg; | ||
1076 | int index; | ||
1077 | uint16_t tot_dsds; | ||
1078 | scsi_qla_host_t *vha = sp->fcport->vha; | ||
1079 | struct fc_bsg_job *bsg_job = ((struct srb_bsg*)sp->ctx)->bsg_job; | ||
1080 | int loop_iterartion = 0; | ||
1081 | int cont_iocb_prsnt = 0; | ||
1082 | int entry_count = 1; | ||
1083 | |||
1084 | ct_iocb->entry_type = CT_IOCB_TYPE; | ||
1085 | ct_iocb->entry_status = 0; | ||
1086 | ct_iocb->sys_define = 0; | ||
1087 | ct_iocb->handle = sp->handle; | ||
1088 | |||
1089 | ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); | ||
1090 | ct_iocb->vp_index = sp->fcport->vp_idx; | ||
1091 | ct_iocb->comp_status = __constant_cpu_to_le16(0); | ||
1092 | |||
1093 | ct_iocb->cmd_dsd_count = | ||
1094 | __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt); | ||
1095 | ct_iocb->timeout = 0; | ||
1096 | ct_iocb->rsp_dsd_count = | ||
1097 | __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt); | ||
1098 | ct_iocb->rsp_byte_count = | ||
1099 | cpu_to_le32(bsg_job->reply_payload.payload_len); | ||
1100 | ct_iocb->cmd_byte_count = | ||
1101 | cpu_to_le32(bsg_job->request_payload.payload_len); | ||
1102 | ct_iocb->dseg_0_address[0] = cpu_to_le32(LSD(sg_dma_address | ||
1103 | (bsg_job->request_payload.sg_list))); | ||
1104 | ct_iocb->dseg_0_address[1] = cpu_to_le32(MSD(sg_dma_address | ||
1105 | (bsg_job->request_payload.sg_list))); | ||
1106 | ct_iocb->dseg_0_len = cpu_to_le32(sg_dma_len | ||
1107 | (bsg_job->request_payload.sg_list)); | ||
1108 | |||
1109 | avail_dsds = 1; | ||
1110 | cur_dsd = (uint32_t *)ct_iocb->dseg_1_address; | ||
1111 | index = 0; | ||
1112 | tot_dsds = bsg_job->reply_payload.sg_cnt; | ||
1113 | |||
1114 | for_each_sg(bsg_job->reply_payload.sg_list, sg, tot_dsds, index) { | ||
1115 | dma_addr_t sle_dma; | ||
1116 | cont_a64_entry_t *cont_pkt; | ||
1117 | |||
1118 | /* Allocate additional continuation packets? */ | ||
1119 | if (avail_dsds == 0) { | ||
1120 | /* | ||
1121 | * Five DSDs are available in the Cont. | ||
1122 | * Type 1 IOCB. | ||
1123 | */ | ||
1124 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha); | ||
1125 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | ||
1126 | avail_dsds = 5; | ||
1127 | cont_iocb_prsnt = 1; | ||
1128 | entry_count++; | ||
1129 | } | ||
1130 | |||
1131 | sle_dma = sg_dma_address(sg); | ||
1132 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
1133 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
1134 | *cur_dsd++ = cpu_to_le32(sg_dma_len(sg)); | ||
1135 | loop_iterartion++; | ||
1136 | avail_dsds--; | ||
1137 | } | ||
1138 | ct_iocb->entry_count = entry_count; | ||
1139 | } | ||
1140 | |||
1028 | int | 1141 | int |
1029 | qla2x00_start_sp(srb_t *sp) | 1142 | qla2x00_start_sp(srb_t *sp) |
1030 | { | 1143 | { |
@@ -1052,6 +1165,13 @@ qla2x00_start_sp(srb_t *sp) | |||
1052 | qla24xx_logout_iocb(sp, pkt): | 1165 | qla24xx_logout_iocb(sp, pkt): |
1053 | qla2x00_logout_iocb(sp, pkt); | 1166 | qla2x00_logout_iocb(sp, pkt); |
1054 | break; | 1167 | break; |
1168 | case SRB_ELS_CMD_RPT: | ||
1169 | case SRB_ELS_CMD_HST: | ||
1170 | qla24xx_els_iocb(sp, pkt); | ||
1171 | break; | ||
1172 | case SRB_CT_CMD: | ||
1173 | qla24xx_ct_iocb(sp, pkt); | ||
1174 | break; | ||
1055 | default: | 1175 | default: |
1056 | break; | 1176 | break; |
1057 | } | 1177 | } |