30 #include <scsi/scsi.h>
31 #include <scsi/scsi_device.h>
32 #include <scsi/scsi_eh.h>
33 #include <scsi/scsi_host.h>
34 #include <scsi/scsi_tcq.h>
35 #include <scsi/scsi_transport.h>
36 #include <scsi/libiscsi.h>
37 #include <scsi/scsi_transport_iscsi.h>
38 #include <linux/if_ether.h>
41 #include "ocs_ini_template.h"
59 uint32_t data_len, uint8_t code);
70 typedef struct ocs_lnx_iscsi_arg_s {
76 #define ocs_scsi_midlayer_result(host_code, scsi_code) (((host_code) << 16) | scsi_code)
78 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
79 #define SCSI_ISCSI_XPORT_ATTR_IS_VISIBLE_V1
81 #define SCSI_ISCSI_XPORT_ATTR_IS_VISIBLE_V0
104 .module = THIS_MODULE,
105 .name =
"Emulex OCS iSCSI midlayer interface",
107 .queuecommand = iscsi_queuecommand,
108 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
109 .change_queue_depth = iscsi_change_queue_depth,
111 .can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
116 .eh_device_reset_handler= iscsi_eh_device_reset,
117 .eh_target_reset_handler = iscsi_eh_recover_target,
118 .use_clustering = ENABLE_CLUSTERING,
119 .target_alloc = iscsi_target_alloc,
120 .max_sectors = 0xFFFF,
126 struct iscsi_task *task = (
struct iscsi_task *)sc->SCp.ptr;
127 ocs_io_t *aborted_io;
137 aborted_io = io_task->io;
140 ocs = aborted_io->ocs;
146 hio = aborted_io->hio;
149 ocs_log_debug(ocs,
"EH aborted on IO type=%d, icd=%d\n",
150 hio->type, hio->icd);
156 ocs_log_test(ocs,
"ocs scsi abort io failed\n");
159 return iscsi_eh_abort(sc);
193 printk(KERN_INFO
"%s: Registered transport with open-iscsi\n", __func__);
195 printk(KERN_INFO
"%s: Failed to register transport with open-iscsi\n", __func__);
236 struct Scsi_Host *shost = NULL;
240 printk(
"%s: entry\n", __func__);
245 printk(
"%s: template registration failed\n", __func__);
248 printk(
"%s: template registration successful\n", __func__);
251 shost = iscsi_host_alloc(&
host_template,
sizeof(*host_private), 0);
253 printk(
"%s: failed to allocate Scsi_Host struct\n", __func__);
258 ocs->ini_ocs.shost = shost;
261 host_private = iscsi_host_priv(shost);
262 host_private->
ocs = ocs;
270 shost->max_cmd_len = 16;
281 printk(
"%s: failed to register unsolicited callback\n", __func__);
282 goto ocs_dealloc_iscsi_host;
288 printk(
"Failed to register a link state callback function\n");
292 ret = iscsi_host_add(shost, &ocs->ocs_os.pdev->dev);
294 printk(
"%s: failed iscsi_host_add\n", __func__);
295 goto ocs_dealloc_iscsi_host;
303 ocs_dealloc_iscsi_host:
304 iscsi_host_free(shost);
305 ocs->ini_ocs.shost = NULL;
324 if (ocs->ini_ocs.shost) {
325 printk(
"%s: Removing scsi%d from SCSI Midlayer\n", __func__, ocs->ini_ocs.shost->host_no);
326 iscsi_host_remove(ocs->ini_ocs.shost);
327 ocs->ini_ocs.shost = NULL;
334 ocs_scsi_unregister_ini_templ(ocs);
336 printk(
"%s: template unregistered\n", __func__);
367 printk(
"%s()\n", __func__);
415 printk(
"New SPORT: %s\n", sport->display_name);
437 printk(
"Del SPORT: %s\n", sport->display_name);
489 printk(
"%s()\n", __func__);
523 scsi_cmd->result = DRIVER_SENSE << 24 |
549 struct scsi_cmnd *scsi_cmd = io->ini_io.scsi_cmd;
550 struct scsi_sense_hdr sshdr;
565 ocs_memcpy(scsi_cmd->sense_buffer, rsp->
sense_data, sense_len);
566 scsi_normalize_sense(scsi_cmd->sense_buffer, sense_len, &sshdr);
568 printk(
"%s: check condition received x%x/x%x/x%x\n",
569 __func__, sshdr.sense_key, sshdr.asc, sshdr.ascq);
576 printk(
"%s: OCS_SCSI_STATUS_ERROR, scsi_status=%d\n",
587 printk(
"%s: Unhandled status=%d\n", __func__, status);
613 struct scsi_cmnd *scsi_cmd,
619 struct scatterlist *sgel = NULL;
622 num_seg = scsi_dma_map(scsi_cmd);
624 if (num_seg > *sgl_cnt) {
626 printk(
"%s: num SGEs=%d requested exceeds max=%d\n",
627 __func__, num_seg, *sgl_cnt);
632 for (i = 0, sgel = scsi_sglist(scsi_cmd); i < (num_seg); i++, sgel = sg_next(sgel)) {
634 sgl[i].
addr = sg_dma_address(sgel);
635 sgl[i].
len = sg_dma_len(sgel);
676 struct iscsi_hdr *hdr = bhs->
dma.virt;
679 ocs_conn_t *ocs_conn;
680 struct iscsi_conn *conn;
681 struct iscsi_task *task;
685 ocs_ep = cxn->ini_node.ocs_ep;
689 conn = ocs_conn->conn;
692 switch(hdr->opcode & ISCSI_OPCODE_MASK) {
695 struct iscsi_login_rsp *rsp_hdr = (
struct iscsi_login_rsp *)hdr;
701 if ((rsp_hdr->status_class == ISCSI_STATUS_CLS_SUCCESS) &&
702 ((rsp_hdr->flags) & ISCSI_FLAG_LOGIN_TRANSIT) &&
703 (ISCSI_LOGIN_NEXT_STAGE(rsp_hdr->flags) == ISCSI_FULL_FEATURE_PHASE)) {
710 task = conn->login_task;
715 task = conn->login_task;
724 if (io_task != NULL) {
732 rc = iscsi_complete_pdu(conn, hdr, (data ? data->
dma.virt : NULL), data_len);
734 printk(
"%s: iscsi_complete_pdu failed, rc=%d\n", __func__, rc);
737 if (io && io->node) {
766 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
781 struct Scsi_Host *shost;
784 shost = ocs->ini_ocs.shost;
828 struct iscsi_conn *conn;
829 ocs_conn_t *ocs_conn;
830 struct iscsi_hdr *hdr;
832 struct iscsi_task *task;
836 unsigned long irq_flags;
837 spinlock_t *session_lock_iscsi;
844 ep = cxn->ini_node.ocs_ep;
850 conn = ocs_conn->conn;
853 io_task = io->ini_io.io_task;
856 task = io_task->
task;
859 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
860 session_lock_iscsi = &task->conn->session->back_lock;
862 session_lock_iscsi = &task->conn->session->lock;
894 spin_lock_irqsave(session_lock_iscsi, irq_flags);
896 iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
897 spin_unlock_irqrestore(session_lock_iscsi, irq_flags);
921 struct iscsi_cls_session *cls_session;
922 struct Scsi_Host *shost;
923 struct iscsi_session *sess;
926 ocs_session_t *ocs_sess;
931 ocs_ep = ep->dd_data;
934 ocs = ocs_ep->
cxn->ocs;
936 shost = ocs->ini_ocs.shost;
942 sizeof(ocs_session_t),
944 initial_cmdsn, ISCSI_MAX_TARGET);
947 sess = cls_session->dd_data;
948 ocs_sess = sess->dd_data;
950 printk(
"%s(): cls_session=%p, ocs_sess=%p sess->state=%d\n",
951 __func__, cls_session, ocs_sess, sess->state);
971 iscsi_session_teardown(cls_session);
983 struct iscsi_cls_conn *
988 struct Scsi_Host *shost;
989 struct iscsi_cls_conn *cls_conn;
990 ocs_conn_t *ocs_conn;
991 struct iscsi_conn *conn;
992 struct iscsi_session *sess;
993 ocs_session_t *ocs_sess;
995 shost = iscsi_session_to_shost(cls_session);
997 host_private = iscsi_host_priv(shost);
998 ocs = host_private->
ocs;
1001 cls_conn = iscsi_conn_setup(cls_session,
sizeof(*ocs_conn), cid);
1006 conn = cls_conn->dd_data;
1007 ocs_conn = conn->dd_data;
1008 ocs_conn->conn = conn;
1011 ocs_conn->ocs_ep = NULL;
1014 sess = cls_session->dd_data;
1015 ocs_sess = sess->dd_data;
1016 ocs_conn->ocs_sess = ocs_sess;
1041 struct iscsi_cls_conn *cls_conn,
1042 u64 transport_fd,
int is_leading)
1044 struct iscsi_conn *conn = cls_conn->dd_data;
1045 ocs_conn_t *ocs_conn = conn->dd_data;
1046 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1048 ocs_t *ocs = host_private->
ocs;
1050 struct iscsi_endpoint *ep;
1056 ep = iscsi_lookup_endpoint(transport_fd);
1061 ocs_ep = ep->dd_data;
1064 if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
1068 ocs_conn->ocs_ep = ocs_ep;
1073 cxn->session = ocs_conn->ocs_sess;
1075 printk(
"%s: connection bound to endpoint\n", __func__);
1091 void *data, uint32_t dt_len)
1110 enum iscsi_param_type param_type,
1111 int param,
char *buf)
1130 enum iscsi_param param,
char *buf)
1148 enum iscsi_param param,
char *buf)
1150 struct iscsi_conn *conn = cls_conn->dd_data;
1151 ocs_conn_t *ocs_conn;
1157 ocs_conn = conn->dd_data;
1160 cxn = ocs_conn->ocs_ep->cxn;
1163 case ISCSI_PARAM_PERSISTENT_PORT:
1164 len = sprintf(buf,
"%d\n", cxn->source_port);
1166 case ISCSI_PARAM_PERSISTENT_ADDRESS:
1167 ocs_strcpy(buf, cxn->source_ip);
1171 len = iscsi_conn_get_param(cls_conn, param, buf);
1191 enum iscsi_param param,
char *buf)
1197 return iscsi_session_get_param(cls_session, param, buf);
1220 enum iscsi_param param,
char *buf,
int buflen)
1222 struct iscsi_conn *conn = cls_conn->dd_data;
1223 struct iscsi_session *session = conn->session;
1224 ocs_conn_t *ocs_conn;
1226 ocs_session_t *ocs_sess;
1232 ocs_conn = conn->dd_data;
1235 cxn = ocs_conn->ocs_ep->cxn;
1236 ocs_sess = cxn->session;
1239 ret = iscsi_set_param(cls_conn, param, buf, buflen);
1244 case ISCSI_PARAM_FIRST_BURST:
1245 printk(
"%s(): cxn=%p first_burst=%d\n", __func__, cxn, session->first_burst);
1247 if (session->first_burst > 8192)
1248 session->first_burst = 8192;
1250 ocs_sess->login_options.first_burst = session->first_burst;
1252 case ISCSI_PARAM_MAX_RECV_DLENGTH:
1253 printk(
"%s(): cxn=%p max_recv_dl=%d\n", __func__, cxn, conn->max_recv_dlength);
1255 if (conn->max_recv_dlength > 65536)
1256 conn->max_recv_dlength = 65536;
1259 cxn->max_rcv_dsl = conn->max_recv_dlength;
1261 case ISCSI_PARAM_MAX_BURST:
1262 printk(
"%s(): cxn=%p max_burst=%d\n", __func__, cxn, session->max_burst);
1264 if (session->max_burst > 262144)
1265 session->max_burst = 262144;
1268 ocs_sess->login_options.max_burst = session->max_burst;
1270 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
1271 printk(
"%s(): cxn=%p max_xmit_dlen=%d\n",
1272 __func__, cxn, conn->max_xmit_dlength);
1275 (conn->max_xmit_dlength == 0))
1279 cxn->max_xmit_dsl = conn->max_xmit_dlength;
1281 case ISCSI_PARAM_PERSISTENT_ADDRESS:
1282 ocs_memcpy(cxn->source_ip, conn->persistent_address, 16);
1284 case ISCSI_PARAM_PERSISTENT_PORT:
1285 cxn->source_port = conn->persistent_port;
1287 case ISCSI_PARAM_HDRDGST_EN:
1288 printk(
"%s(): cxn=%p HdrDigest=%d\n",
1289 __func__, cxn, conn->hdrdgst_en);
1290 cxn->hdr_digest = conn->hdrdgst_en;
1292 case ISCSI_PARAM_DATADGST_EN:
1293 printk(
"%s(): cxn=%p DataDigest=%d\n",
1294 __func__, cxn, conn->datadgst_en);
1295 cxn->data_digest = conn->datadgst_en;
1297 case ISCSI_PARAM_IMM_DATA_EN:
1298 printk(
"%s(): cxn=%p immediate_data=%d\n",
1299 __func__, cxn, session->imm_data_en);
1300 ocs_sess->login_options.immediate_data = session->imm_data_en;
1323 enum iscsi_host_param param,
char *buf,
int buflen)
1327 ret = iscsi_host_set_param(shost, param, buf, buflen);
1348 enum iscsi_host_param param,
char *buf)
1351 ocs_t *ocs = host_private->
ocs;
1355 case ISCSI_HOST_PARAM_HWADDRESS:
1358 case ISCSI_HOST_PARAM_INITIATOR_NAME:
1360 status = strlen(buf);
1363 status = iscsi_host_get_param(shost, param, buf);
1380 struct iscsi_stats *stats)
1399 struct iscsi_conn *conn)
1401 struct iscsi_session *session = conn->session;
1431 ocs_conn_t *ocs_conn;
1435 struct iscsi_conn *conn;
1438 conn = cls_conn->dd_data;
1440 ocs_conn = conn->dd_data;
1442 ocs_ep = ocs_conn->ocs_ep;
1452 iscsi_conn_start(cls_conn);
1471 struct iscsi_session *session;
1472 ocs_conn_t *ocs_conn;
1475 ocs_session_t *ocs_session;
1478 ocs_conn = conn->dd_data;
1480 session = conn->session;
1482 ocs_ep = ocs_conn->ocs_ep;
1486 ocs_session = cxn->session;
1490 cxn->data_digest = conn->datadgst_en;
1491 cxn->hdr_digest = conn->hdrdgst_en;
1492 cxn->max_rcv_dsl = conn->max_recv_dlength;
1493 cxn->max_xmit_dsl = conn->max_xmit_dlength;
1494 cxn->stat_sn = conn->exp_statsn;
1495 ocs_session->login_options.max_burst = session->max_burst;
1496 ocs_session->login_options.first_burst = session->first_burst;
1497 ocs_session->login_options.error_recovery_level = session->erl;
1498 ocs_session->login_options.initial_r2t = session->initial_r2t_en;
1499 ocs_session->login_options.immediate_data = session->imm_data_en;
1521 struct sockaddr_in *daddr_in = (
struct sockaddr_in *)addr;
1522 struct sockaddr_in6 *daddr_in6 = (
struct sockaddr_in6 *)addr;
1523 if (addr->sa_family == PF_INET) {
1524 __be32 s_addr = daddr_in->sin_addr.s_addr;
1527 hal_ip->
ip_address[1] = (s_addr & 0x0000ff00) >> 8;
1528 hal_ip->
ip_address[2] = (s_addr & 0x00ff0000) >> 16;
1529 hal_ip->
ip_address[3] = (s_addr & 0xff000000) >> 24;
1530 *port = ntohs(daddr_in->sin_port);
1531 }
else if (addr->sa_family == PF_INET6) {
1533 memcpy(hal_ip->
ip_address, &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
1534 *port = ntohs(daddr_in6->sin6_port);
1557 struct iscsi_endpoint *
1563 struct iscsi_endpoint *ep;
1566 uint16_t remote_port = 0;
1567 ocs_cxn_t *cxn = NULL;
1570 host_private = iscsi_host_priv(shost);
1573 return ERR_PTR(ret);
1576 ocs = host_private->
ocs;
1577 ep = iscsi_create_endpoint(
sizeof(
ocs_ep_t));
1580 return ERR_PTR(ret);
1583 ocs_ep = ep->dd_data;
1590 printk(
"%s(): failed to translate IP address\n", __func__);
1597 printk(
"%s(): attempt to connect to IPv4 address %d.%d.%d.%d\n",
1604 uint16_t *word = (uint16_t *)remote_ip.
ip_address;
1605 printk(
"%s(): attempt to connect to IPv6 address %x:%x:%x:%x:%x:%x:%x:%x\n",
1618 printk(
"%s(): connection failed, status=%d\n", __func__, ret);
1623 printk(
"%s(): connection success\n", __func__);
1628 cxn->ini_node.ocs_ep = ocs_ep;
1632 iscsi_destroy_endpoint(ep);
1633 return ERR_PTR(ret);
1658 ocs_ep = ep->dd_data;
1662 ret = (ocs_ep->
cxn ? 1 : 0);
1680 ocs_cxn_t *cxn = NULL;
1689 ocs_ep = ep->dd_data;
1695 iscsi_suspend_queue(ocs_ep->
ocs_conn->conn);
1704 printk(
"%s(): disconnect failed, status=%d\n", __func__, ret);
1709 printk(
"%s(): disconnect success, ep=%p ocs_ep=%p cxn=%p\n",
1710 __func__, ep, ocs_ep, cxn);
1715 printk(
"%s(): upload failed, status=%d\n", __func__, ret);
1720 printk(
"%s(): upload success, ep=%p ocs_ep=%p cxn=%p\n",
1721 __func__, ep, ocs_ep, cxn);
1748 uint32_t max_cmdsn, uint8_t response)
1753 ocs_conn_t *ocs_conn;
1754 struct iscsi_conn *conn;
1761 ep = cxn->ini_node.ocs_ep;
1767 io_task = io->ini_io.io_task;
1770 conn = ocs_conn->conn;
1807 uint32_t max_cmdsn, uint8_t response)
1809 struct iscsi_hdr *hdr;
1813 ocs_conn_t *ocs_conn;
1814 struct iscsi_conn *conn;
1822 ep = cxn->ini_node.ocs_ep;
1828 io_task = io->ini_io.io_task;
1831 conn = ocs_conn->conn;
1846 hdr = (
struct iscsi_hdr *)io->bhs;
1850 rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
1852 if (rc == ISCSI_ERR_BAD_OPCODE) {
1853 printk(
"%s: iscsi_complete_pdu returns BAD_OPCODE %d\n",
1854 __func__, hdr->opcode);
1856 printk(
"%s: iscsi_complete_pdu failed, rc=%d\n", __func__, rc);
1883 uint32_t max_cmdsn, uint8_t response)
1885 struct iscsi_hdr *hdr;
1889 ocs_conn_t *ocs_conn;
1890 struct iscsi_conn *conn;
1900 ep = cxn->ini_node.ocs_ep;
1906 io_task = io->ini_io.io_task;
1909 conn = ocs_conn->conn;
1924 hdr = (
struct iscsi_hdr *)io->bhs;
1934 nop_hdr->
expCmdSN = ocs_htobe32(exp_cmdsn);
1935 nop_hdr->
maxCmdSN = ocs_htobe32(max_cmdsn);
1936 nop_hdr->
opcode = ISCSI_OP_NOOP_IN;
1937 nop_hdr->
ttt = 0xffffffff;
1941 rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
1943 if (rc == ISCSI_ERR_BAD_OPCODE) {
1944 printk(
"%s: iscsi_complete_pdu returns BAD_OPCODE %d\n",
1945 __func__, hdr->opcode);
1947 printk(
"%s: iscsi_complete_pdu failed, rc=%d\n", __func__, rc);
1971 ocs_io_t *io = io_task->
io;
1972 struct iscsi_conn *conn = task->conn;
1974 ocs_conn_t *ocs_conn = conn->dd_data;
1984 cxn = ocs_conn->ocs_ep->cxn;
1993 switch (bhs->
opcode & ISCSI_OPCODE_MASK) {
2001 if (nop_hdr->
ttt == 0xffffffff) {
2002 if (nop_hdr->
itt == 0xffffffff) {
2044 printk(
"%s: unhandled opcode=%d\n", __func__, bhs->
opcode);
2049 (
void *)task->data, task->data_count,
2050 is_login, set_dm, cb);
2070 struct scsi_cmnd *scsi_cmnd = task->sc;
2078 if (scsi_cmnd != NULL) {
2079 scsi_cmnd->result = DID_NO_CONNECT;
2080 scsi_cmnd->scsi_done(scsi_cmnd);
2106 ocs_io_t *io = NULL;
2107 struct iscsi_conn *conn = task->conn;
2108 ocs_conn_t *ocs_conn = conn->dd_data;
2109 ocs_cxn_t *ocs_cxn = ocs_conn->ocs_ep->cxn;
2110 ocs_t *ocs = ocs_cxn->ocs;
2111 struct scsi_cmnd *scsi_cmnd = task->sc;
2118 io_task->
task = task;
2122 if (scsi_cmnd == NULL) {
2131 ocs_memset(&io->ini_io, 0,
sizeof(io->ini_io));
2132 io->ini_io.scsi_cmd = scsi_cmnd;
2133 io->ini_io.done = scsi_cmnd->scsi_done;
2134 io->ini_io.io_task = io_task;
2138 num_sg = scsi_dma_map(scsi_cmnd);
2141 printk(
"%s: scsi_dma_map returned %d\n", __func__, num_sg);
2146 xferlen = scsi_bufflen(scsi_cmnd);
2148 if (scsi_sg_count(scsi_cmnd)) {
2150 sgl_count =
sizeof(sgl)/
sizeof(sgl[0]);
2153 switch (scsi_cmnd->sc_data_direction) {
2154 case DMA_FROM_DEVICE:
2157 scsi_cmnd->cmnd, scsi_cmnd->cmd_len, NULL,
2158 sgl, sgl_count, scsi_bufflen(scsi_cmnd),
2164 scsi_cmnd->cmnd, scsi_cmnd->cmd_len, NULL,
2165 sgl, sgl_count, scsi_bufflen(scsi_cmnd),
2170 printk(
"%s: default %d\n", __func__, scsi_cmnd->sc_data_direction);
2175 scsi_cmnd->cmnd, scsi_cmnd->cmd_len,
2205 io_task = task->dd_data;
2242 struct iscsi_conn *conn;
2243 ocs_conn_t *ocs_conn;
2252 io_task = task->dd_data;
2258 ocs_conn = conn->dd_data;
2261 ocs_ep = ocs_conn->ocs_ep;
2267 ocs_iscsi = cxn->iscsi;
2282 printk(
"%s: No io is available", __func__);
2289 io->ini_io.io_task = io_task;
2300 task->hdr = (
struct iscsi_hdr *)io->bhs;
2319 #if defined(SCSI_ISCSI_XPORT_ATTR_IS_VISIBLE_V0)
2322 #if defined(SCSI_ISCSI_XPORT_ATTR_IS_VISIBLE_V1)
2326 switch (param_type) {
2327 case ISCSI_NET_PARAM:
2329 case ISCSI_NET_PARAM_IFACE_ENABLE:
2330 case ISCSI_NET_PARAM_IPV4_ADDR:
2331 case ISCSI_NET_PARAM_IPV4_SUBNET:
2332 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
2333 case ISCSI_NET_PARAM_IPV4_GW:
2334 case ISCSI_NET_PARAM_IPV6_ADDR:
2335 case ISCSI_NET_PARAM_VLAN_ID:
2336 case ISCSI_NET_PARAM_VLAN_PRIORITY:
2337 case ISCSI_NET_PARAM_VLAN_ENABLED:
2342 case ISCSI_HOST_PARAM:
2344 case ISCSI_HOST_PARAM_HWADDRESS:
2345 case ISCSI_HOST_PARAM_INITIATOR_NAME:
2350 case ISCSI_HOST_PARAM_PORT_STATE:
2351 case ISCSI_HOST_PARAM_PORT_SPEED:
2359 case ISCSI_PARAM_MAX_RECV_DLENGTH:
2360 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
2361 case ISCSI_PARAM_HDRDGST_EN:
2362 case ISCSI_PARAM_DATADGST_EN:
2363 case ISCSI_PARAM_CONN_ADDRESS:
2364 case ISCSI_PARAM_CONN_PORT:
2365 case ISCSI_PARAM_EXP_STATSN:
2366 case ISCSI_PARAM_PERSISTENT_ADDRESS:
2367 case ISCSI_PARAM_PERSISTENT_PORT:
2368 case ISCSI_PARAM_PING_TMO:
2369 case ISCSI_PARAM_RECV_TMO:
2370 case ISCSI_PARAM_INITIAL_R2T_EN:
2371 case ISCSI_PARAM_MAX_R2T:
2372 case ISCSI_PARAM_IMM_DATA_EN:
2373 case ISCSI_PARAM_FIRST_BURST:
2374 case ISCSI_PARAM_MAX_BURST:
2375 case ISCSI_PARAM_PDU_INORDER_EN:
2376 case ISCSI_PARAM_DATASEQ_INORDER_EN:
2377 case ISCSI_PARAM_ERL:
2378 case ISCSI_PARAM_TARGET_NAME:
2379 case ISCSI_PARAM_TPGT:
2380 case ISCSI_PARAM_USERNAME:
2381 case ISCSI_PARAM_PASSWORD:
2382 case ISCSI_PARAM_USERNAME_IN:
2383 case ISCSI_PARAM_PASSWORD_IN:
2384 case ISCSI_PARAM_FAST_ABORT:
2385 case ISCSI_PARAM_ABORT_TMO:
2386 case ISCSI_PARAM_LU_RESET_TMO:
2387 case ISCSI_PARAM_IFACE_NAME:
2388 case ISCSI_PARAM_INITIATOR_NAME:
2408 .owner = THIS_MODULE,
2410 .caps = (CAP_RECOVERY_L0 |
2415 CAP_DIGEST_OFFLOAD |
2416 CAP_DATA_PATH_OFFLOAD),
2421 .destroy_conn = iscsi_conn_teardown,
2431 .stop_conn = iscsi_conn_stop,
2432 .send_pdu = iscsi_conn_send_pdu,
2441 .session_recovery_timedout = iscsi_session_recovery_timedout,
int32_t ocs_iscsi_unassisted_pdu_send(ocs_t *ocs, ocs_io_t *io, ocs_cxn_t *cxn, void *bhs, void *data, uint32_t data_size, bool is_login, bool set_dm, ocs_iscsi_pdu_cb_t cb)
static void ocs_session_max_cmd_sn_set(ocs_cxn_t *cxn, uint32_t max_cmd_sn)
int32_t ocs_scsi_ini_new_sport(ocs_sport_t *sport)
Process creation of a new SPORT.
int ocs_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t dt_len)
#define OCS_DEFAULT_SG_SEG_CNT
int ocs_iface_get_param(struct iscsi_iface *iface, enum iscsi_param_type param_type, int param, char *buf)
int ocs_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
Poll to see if a connection is established.
ocs_link_state_e
enum identifying the link state.
int32_t ocs_iscsi_register_link_state_callback(ocs_t *ocs, ocs_link_state_cb_t cb)
Register to receive link state change notifications.
void ocs_session_destroy(struct iscsi_cls_session *cls_session)
Destroy an iSCSI session.
struct iscsi_cls_session * ocs_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth, u32 initial_cmdsn)
Create a new iscsi session.
int32_t ocs_scsi_ini_new_domain(ocs_domain_t *domain)
Accept new domain notification.
ocs_scsi_ini_template_t ocs_iscsi_ini_template
struct iscsi_endpoint * openiscsi_ep
int32_t ocs_scsi_ini_driver_init(int32_t initiator)
Initialize initiator client.
int32_t ocs_iscsi_mtask_cb_tcp_ack_wait_rsp(ocs_io_t *io, uint32_t exp_cmdsn, uint32_t max_cmdsn, uint8_t response)
Completion handler for non-SCSI initiator tasks that complete on TCP ACK.
Defines the generic iSCSI basic header segment.
#define OCS_BHS_ALLOC_SIZE
static int32_t ocs_lnx_xport_unsol_cb(void *arg, ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *bhs, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len, uint8_t code)
Unsolicited event handler.
static int32_t ocs_lnx_xport_io_cb(ocs_io_t *io, ocs_scsi_io_status_e status, ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg)
IO completion handler for iSCSI initiator.
static void ocs_lnx_xport_fail_session(struct iscsi_cls_session *cls_session)
Helper function for marking sessions as failed.
int32_t ocs_ramlog_printf(void *os, const char *fmt,...)
Append formatted printf data to a ramlog buffer.
static struct scsi_transport_template * transport_template
uint32_t sense_data_length
ocs_hal_target_login_options_t lgn_options
ocs_hal_abort_type_e
HAL abort types.
static void ocs_session_calc_cmd_window(ocs_cxn_t *cxn)
static int ocs_conn_update_context(struct iscsi_conn *conn)
int32_t ocs_iscsi_mtask_cb_with_rsp(ocs_io_t *io, uint32_t exp_cmdsn, uint32_t max_cmdsn, uint8_t response)
Completion handler for non-SCSI initiator tasks.
bool ocs_scsi_check_cxn_wq_full(ocs_t *ocs, ocs_cxn_t *cxn)
Check Connection WQ's full status.
char * ocs_iscsi_ini_get_name(ocs_t *ocs)
Return this initiator's name.
generic scatter-gather list structure
void ocs_cleanup_task(struct iscsi_task *task)
int32_t ocs_iscsi_send_context_udpate(ocs_cxn_t *cxn)
Sends the login parameters to the FW.
void ocs_scsi_io_free(ocs_io_t *io)
Free a SCSI IO context.
#define CONN_STATE_NEW_CONN
int32_t ocs_iscsi_mtask_cb_tcp_ack_no_rsp(ocs_io_t *io, uint32_t exp_cmdsn, uint32_t max_cmdsn, uint8_t response)
Completion handler for non-SCSI initiator tasks that complete on TCP ACK.
defines the parameters for an IO based on the IO type.
int32_t ocs_scsi_map_sgl(ocs_t *, struct scsi_cmnd *, ocs_scsi_sgl_t *, uint32_t *)
Map mid-layer SGLs to ocs SGLs.
int32_t ocs_scsi_send_rd_io(ocs_node_t *node, ocs_io_t *io, uint32_t lun, void *cdb, uint32_t cdb_len, ocs_scsi_dif_info_t *dif_info, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg)
Initiate initiator read IO.
void ocs_print_stack(void)
static void ocs_task_cleanup(struct iscsi_task *task)
Clean up an iSCSI task.
int32_t ocs_xport_control(ocs_xport_t *xport, ocs_xport_ctrl_e cmd,...)
Perform transport attach function.
uint8_t * ocs_iscsi_mac_get(ocs_t *ocs)
Gets the MAC address of the iSCSI device.
static void ocs_scsi_cmnd_result_chk_cond(struct scsi_cmnd *scsi_cmd)
Set scsi_cmnd check condition.
ocs_io_task_state_e task_state
int ocs_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf)
int32_t ocs_scsi_ini_del_device(ocs_t *ocs)
Tears down initiator members of ocs structure.
void ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Generate driver dump data for debugging.
int ocs_scsi_abort_io(ocs_hal_t *hal, ocs_hal_io_t *hio, ocs_hal_abort_type_e abort_type)
struct scsi_cmnd * scsi_cmnd
int ocs_conn_start(struct iscsi_cls_conn *cls_conn)
Offload of session to chip.
int ocs_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf)
static void ocs_lnx_xport_link_state(ocs_t *ocs, ocs_link_state_e link_state)
Called when the link changes state.
ocs_hal_ip_type_e ip_type
Defines a wrapper for the RQ payload buffers so that we can place it back on the proper queue...
int32_t ocs_scsi_new_target(ocs_node_t *node)
Receive notification of a new SCSI target node.
static void ocs_session_exp_cmd_sn_set(ocs_cxn_t *cxn, uint32_t exp_cmd_sn)
Defines the iSCSI nop-out PDU header.
struct iscsi_endpoint * ocs_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, int non_blocking)
Ask the chip to create TCP connection.
struct ocs_hal_io_param_t::@17 context_upd
static int ocs_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
Allocate a new PDU.
void ocs_iscsi_rx_buffers_free(ocs_iscsi_t *iscsi, ocs_hal_rq_buffer_t *header, ocs_hal_rq_buffer_t *payload)
Add a receive buffer pair to the Receive Queue, if an error is received, then queue the buffer...
static int ocs_xmit_mtask(struct iscsi_task *task)
Transmit a management task.
static uint32_t ocs_session_exp_cmd_sn_get(ocs_cxn_t *cxn)
ocs_scsi_del_target_reason_e
struct scsi_host_template host_template
Host Template.
int ocs_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, u64 transport_fd, int is_leading)
Binds an iSCSI connection to an endpoint.
int32_t ocs_scsi_send_nodata_io(ocs_node_t *node, ocs_io_t *io, uint32_t lun, void *cdb, uint32_t cdb_len, ocs_scsi_rsp_io_cb_t cb, void *arg)
Initiate initiator SCSI command with no data.
int32_t ocs_scsi_cmd_cb(ocs_io_t *, ocs_scsi_io_status_e, ocs_scsi_cmd_resp_t *, uint32_t, void *)
SCSI IO callback function.
int32_t ocs_scsi_ini_driver_exit(int32_t initiator)
initiator client exit
struct iscsi_cls_conn * ocs_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
Create an instance of iSCSI connection.
#define OCS_ISCSI_LOGIN_MAX_RECV_DATA_SEG_LEN
umode_t ocs_attr_is_visible(int param_type, int param)
Return sysfs visibility for a parameter.
structure wrapping an IP address together with it's type.
#define ISCSI_RESP_LOGOUT
static int ocs_task_xmit(struct iscsi_task *task)
Transmit an iSCSI task.
void ocs_set_update_ctx_options(ocs_hal_io_param_t *iparam, struct iscsi_conn *conn)
Set UPDATE CONTEXT options.
int ocs_ep_get_param(struct iscsi_endpoint *ep, enum iscsi_param param, char *buf)
static int ocs_eh_abort(struct scsi_cmnd *sc)
uint8_t error_recovery_level
int32_t ocs_scsi_ini_new_device(ocs_t *ocs)
Initializes any initiator fields on the ocs structure.
int ocs_set_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf, int buflen)
void ocs_scsi_ini_del_sport(ocs_sport_t *sport)
Process deletion of a SPORT.
int32_t ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_e reason)
Delete a SCSI target node.
static int ocs_sockaddr_to_hal_ip(struct sockaddr *addr, ocs_hal_ip_address_t *hal_ip, uint16_t *port)
struct iscsi_transport ocs_lnx_xport_iscsi
iSCSI transport entry points.
static uint32_t ocs_session_cmd_window_get(ocs_cxn_t *cxn)
int ocs_session_get_param(struct iscsi_cls_session *cls_session, enum iscsi_param param, char *buf)
void ocs_iscsi_unregister_link_state_callback(ocs_t *ocs, ocs_link_state_cb_t cb)
Unregister a link state change callback.
#define ocs_assert(cond,...)
#define CONN_STATE_FULL_FEATURE
#define ocs_scsi_midlayer_result(host_code, scsi_code)
int32_t ocs_scsi_send_wr_io(ocs_node_t *node, ocs_io_t *io, uint32_t lun, void *cdb, uint32_t cdb_len, ocs_scsi_dif_info_t *dif_info, ocs_scsi_sgl_t *sgl, uint32_t sgl_count, uint32_t wire_len, ocs_scsi_rsp_io_cb_t cb, void *arg)
Initiate initiator write IO.
#define OCS_SCSI_CALL_COMPLETE
int32_t(* ocs_iscsi_pdu_cb_t)(ocs_io_t *io, uint32_t exp_cmdsn, uint32_t max_cmdsn, uint8_t response)
ocs_io_t * ocs_scsi_io_alloc(ocs_node_t *node, ocs_scsi_io_role_e role)
allocate a SCSI IO context.
const char const char * fmt
Defines the iSCSI nop-in PDU header.
uint32_t ocs_scsi_get_property(ocs_t *ocs, ocs_scsi_property_e prop)
Return SCSI API integer valued property.
void ocs_scsi_ini_del_domain(ocs_domain_t *domain)
Accept domain lost notification.
ocs_session_login_options_t session_options
int ocs_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf, int buflen)
void ocs_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
void ocs_ep_disconnect(struct iscsi_endpoint *ep)
Tears down the TCP connection.