zfcp_fc.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * zfcp device driver
  3. *
  4. * Fibre Channel related definitions and inline functions for the zfcp
  5. * device driver
  6. *
  7. * Copyright IBM Corporation 2009
  8. */
  9. #ifndef ZFCP_FC_H
  10. #define ZFCP_FC_H
  11. #include <scsi/fc/fc_els.h>
  12. #include <scsi/fc/fc_fcp.h>
  13. #include <scsi/fc/fc_ns.h>
  14. #include <scsi/scsi_cmnd.h>
  15. #include <scsi/scsi_tcq.h>
  16. #define ZFCP_FC_CT_SIZE_PAGE (PAGE_SIZE - sizeof(struct fc_ct_hdr))
  17. #define ZFCP_FC_GPN_FT_ENT_PAGE (ZFCP_FC_CT_SIZE_PAGE \
  18. / sizeof(struct fc_gpn_ft_resp))
  19. #define ZFCP_FC_GPN_FT_NUM_BUFS 4 /* memory pages */
  20. #define ZFCP_FC_GPN_FT_MAX_SIZE (ZFCP_FC_GPN_FT_NUM_BUFS * PAGE_SIZE \
  21. - sizeof(struct fc_ct_hdr))
  22. #define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
  23. (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
  24. /**
  25. * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
  26. * @ct_hdr: FC GS common transport header
  27. * @gid_pn: GID_PN request
  28. */
  29. struct zfcp_fc_gid_pn_req {
  30. struct fc_ct_hdr ct_hdr;
  31. struct fc_ns_gid_pn gid_pn;
  32. } __packed;
  33. /**
  34. * struct zfcp_fc_gid_pn_resp - container for ct header plus gid_pn response
  35. * @ct_hdr: FC GS common transport header
  36. * @gid_pn: GID_PN response
  37. */
  38. struct zfcp_fc_gid_pn_resp {
  39. struct fc_ct_hdr ct_hdr;
  40. struct fc_gid_pn_resp gid_pn;
  41. } __packed;
  42. /**
  43. * struct zfcp_fc_gid_pn - everything required in zfcp for gid_pn request
  44. * @ct: data passed to zfcp_fsf for issuing fsf request
  45. * @sg_req: scatterlist entry for request data
  46. * @sg_resp: scatterlist entry for response data
  47. * @gid_pn_req: GID_PN request data
  48. * @gid_pn_resp: GID_PN response data
  49. */
  50. struct zfcp_fc_gid_pn {
  51. struct zfcp_send_ct ct;
  52. struct scatterlist sg_req;
  53. struct scatterlist sg_resp;
  54. struct zfcp_fc_gid_pn_req gid_pn_req;
  55. struct zfcp_fc_gid_pn_resp gid_pn_resp;
  56. struct zfcp_port *port;
  57. };
  58. /**
  59. * struct zfcp_fc_gpn_ft - container for ct header plus gpn_ft request
  60. * @ct_hdr: FC GS common transport header
  61. * @gpn_ft: GPN_FT request
  62. */
  63. struct zfcp_fc_gpn_ft_req {
  64. struct fc_ct_hdr ct_hdr;
  65. struct fc_ns_gid_ft gpn_ft;
  66. } __packed;
  67. /**
  68. * struct zfcp_fc_gpn_ft_resp - container for ct header plus gpn_ft response
  69. * @ct_hdr: FC GS common transport header
  70. * @gpn_ft: Array of gpn_ft response data to fill one memory page
  71. */
  72. struct zfcp_fc_gpn_ft_resp {
  73. struct fc_ct_hdr ct_hdr;
  74. struct fc_gpn_ft_resp gpn_ft[ZFCP_FC_GPN_FT_ENT_PAGE];
  75. } __packed;
  76. /**
  77. * struct zfcp_fc_gpn_ft - zfcp data for gpn_ft request
  78. * @ct: data passed to zfcp_fsf for issuing fsf request
  79. * @sg_req: scatter list entry for gpn_ft request
  80. * @sg_resp: scatter list entries for gpn_ft responses (per memory page)
  81. */
  82. struct zfcp_fc_gpn_ft {
  83. struct zfcp_send_ct ct;
  84. struct scatterlist sg_req;
  85. struct scatterlist sg_resp[ZFCP_FC_GPN_FT_NUM_BUFS];
  86. };
  87. /**
  88. * struct zfcp_fc_els_adisc - everything required in zfcp for issuing ELS ADISC
  89. * @els: data required for issuing els fsf command
  90. * @req: scatterlist entry for ELS ADISC request
  91. * @resp: scatterlist entry for ELS ADISC response
  92. * @adisc_req: ELS ADISC request data
  93. * @adisc_resp: ELS ADISC response data
  94. */
  95. struct zfcp_fc_els_adisc {
  96. struct zfcp_send_els els;
  97. struct scatterlist req;
  98. struct scatterlist resp;
  99. struct fc_els_adisc adisc_req;
  100. struct fc_els_adisc adisc_resp;
  101. };
  102. /**
  103. * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
  104. * @fcp: fcp_cmnd to setup
  105. * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
  106. */
  107. static inline
  108. void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
  109. {
  110. char tag[2];
  111. int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
  112. if (scsi_populate_tag_msg(scsi, tag)) {
  113. switch (tag[0]) {
  114. case MSG_ORDERED_TAG:
  115. fcp->fc_pri_ta |= FCP_PTA_ORDERED;
  116. break;
  117. case MSG_SIMPLE_TAG:
  118. fcp->fc_pri_ta |= FCP_PTA_SIMPLE;
  119. break;
  120. };
  121. } else
  122. fcp->fc_pri_ta = FCP_PTA_SIMPLE;
  123. if (scsi->sc_data_direction == DMA_FROM_DEVICE)
  124. fcp->fc_flags |= FCP_CFL_RDDATA;
  125. if (scsi->sc_data_direction == DMA_TO_DEVICE)
  126. fcp->fc_flags |= FCP_CFL_WRDATA;
  127. memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
  128. fcp->fc_dl = scsi_bufflen(scsi);
  129. }
  130. /**
  131. * zfcp_fc_fcp_tm - setup FCP command as task management command
  132. * @fcp: fcp_cmnd to setup
  133. * @dev: scsi_device where to send the task management command
  134. * @tm: task management flags to setup tm command
  135. */
  136. static inline
  137. void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
  138. {
  139. int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
  140. fcp->fc_tm_flags |= tm_flags;
  141. }
  142. /**
  143. * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
  144. * @fcp_rsp: FCP RSP IU to evaluate
  145. * @scsi: SCSI command where to update status and sense buffer
  146. */
  147. static inline
  148. void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
  149. struct scsi_cmnd *scsi)
  150. {
  151. struct fcp_resp_rsp_info *rsp_info;
  152. char *sense;
  153. u32 sense_len, resid;
  154. u8 rsp_flags;
  155. set_msg_byte(scsi, COMMAND_COMPLETE);
  156. scsi->result |= fcp_rsp->resp.fr_status;
  157. rsp_flags = fcp_rsp->resp.fr_flags;
  158. if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
  159. rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
  160. if (rsp_info->rsp_code == FCP_TMF_CMPL)
  161. set_host_byte(scsi, DID_OK);
  162. else {
  163. set_host_byte(scsi, DID_ERROR);
  164. return;
  165. }
  166. }
  167. if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
  168. sense = (char *) &fcp_rsp[1];
  169. if (rsp_flags & FCP_RSP_LEN_VAL)
  170. sense += fcp_rsp->ext.fr_sns_len;
  171. sense_len = min(fcp_rsp->ext.fr_sns_len,
  172. (u32) SCSI_SENSE_BUFFERSIZE);
  173. memcpy(scsi->sense_buffer, sense, sense_len);
  174. }
  175. if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
  176. resid = fcp_rsp->ext.fr_resid;
  177. scsi_set_resid(scsi, resid);
  178. if (scsi_bufflen(scsi) - resid < scsi->underflow &&
  179. !(rsp_flags & FCP_SNS_LEN_VAL) &&
  180. fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
  181. set_host_byte(scsi, DID_ERROR);
  182. }
  183. }
  184. #endif