Deleted Added
full compact
3a4
> * Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
45c46
< __FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 288731 2015-10-05 08:55:59Z mav $");
---
> __FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 288732 2015-10-05 08:57:16Z mav $");
87,105d87
< * Size and alignment macros needed for Copan-specific HA hardware. These
< * can go away when the HA code is re-written, and uses busdma for any
< * hardware.
< */
< #define CTL_ALIGN_8B(target, source, type) \
< if (((uint32_t)source & 0x7) != 0) \
< target = (type)(source + (0x8 - ((uint32_t)source & 0x7)));\
< else \
< target = (type)source;
<
< #define CTL_SIZE_8B(target, size) \
< if ((size & 0x7) != 0) \
< target = size + (0x8 - (size & 0x7)); \
< else \
< target = size;
<
< #define CTL_ALIGN_8B_MARGIN 16
<
< /*
354,359d335
< /*
< * XXX KDM move these into the softc.
< */
< static int rcv_sync_msg;
< static uint8_t ctl_pause_rtr;
<
378d353
< #ifdef notyet
382c357
< #endif
---
> static void ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest);
398,401d372
< /**
< static void ctl_failover_change_pages(struct ctl_softc *softc,
< struct ctl_scsiio *ctsio, int master);
< **/
438,441c409,413
< //static int ctl_check_rtr(union ctl_io *pending_io, struct ctl_softc *softc);
< #ifdef notyet
< static void ctl_failover(void);
< #endif
---
> static void ctl_failover_lun(struct ctl_lun *lun);
> static void ctl_est_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
> static void ctl_est_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
> static void ctl_clr_ua(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua);
> static void ctl_clr_ua_all(struct ctl_lun *lun, uint32_t except, ctl_ua_type ua);
480d451
< #ifdef notyet
482d452
< #endif
489a460,464
> static uint64_t ctl_get_prkey(struct ctl_lun *lun, uint32_t residx);
> static void ctl_clr_prkey(struct ctl_lun *lun, uint32_t residx);
> static void ctl_alloc_prkey(struct ctl_lun *lun, uint32_t residx);
> static void ctl_set_prkey(struct ctl_lun *lun, uint32_t residx, uint64_t key);
>
522c497,501
< #ifdef notyet
---
> static struct ctl_frontend ha_frontend =
> {
> .name = "ha",
> };
>
544c523
< sizeof(ctsio->sense_data));
---
> msg_info->scsi.sense_len);
563,590d541
< #if 0
< /*
< * Attempt to catch the situation where an I/O has
< * been freed, and we're using it again.
< */
< if (ctsio->io_hdr.io_type == 0xff) {
< union ctl_io *tmp_io;
< tmp_io = (union ctl_io *)ctsio;
< printf("%s: %p use after free!\n", __func__,
< ctsio);
< printf("%s: type %d msg %d cdb %x iptl: "
< "%u:%u:%u tag 0x%04x "
< "flag %#x status %x\n",
< __func__,
< tmp_io->io_hdr.io_type,
< tmp_io->io_hdr.msg_type,
< tmp_io->scsiio.cdb[0],
< tmp_io->io_hdr.nexus.initid,
< tmp_io->io_hdr.nexus.targ_port,
< tmp_io->io_hdr.nexus.targ_lun,
< (tmp_io->io_hdr.io_type ==
< CTL_IO_TASK) ?
< tmp_io->taskio.tag_num :
< tmp_io->scsiio.tag_num,
< tmp_io->io_hdr.flags,
< tmp_io->io_hdr.status);
< }
< #endif
594a546,862
> void
> ctl_isc_announce_lun(struct ctl_lun *lun)
> {
> struct ctl_softc *softc = lun->ctl_softc;
> union ctl_ha_msg *msg;
> struct ctl_ha_msg_lun_pr_key pr_key;
> int i, k;
>
> if (softc->ha_link != CTL_HA_LINK_ONLINE)
> return;
> mtx_lock(&lun->lun_lock);
> i = sizeof(msg->lun);
> if (lun->lun_devid)
> i += lun->lun_devid->len;
> i += sizeof(pr_key) * lun->pr_key_count;
> alloc:
> mtx_unlock(&lun->lun_lock);
> msg = malloc(i, M_CTL, M_WAITOK);
> mtx_lock(&lun->lun_lock);
> k = sizeof(msg->lun);
> if (lun->lun_devid)
> k += lun->lun_devid->len;
> k += sizeof(pr_key) * lun->pr_key_count;
> if (i < k) {
> free(msg, M_CTL);
> i = k;
> goto alloc;
> }
> bzero(&msg->lun, sizeof(msg->lun));
> msg->hdr.msg_type = CTL_MSG_LUN_SYNC;
> msg->hdr.nexus.targ_lun = lun->lun;
> msg->hdr.nexus.targ_mapped_lun = lun->lun;
> msg->lun.flags = lun->flags;
> msg->lun.pr_generation = lun->PRGeneration;
> msg->lun.pr_res_idx = lun->pr_res_idx;
> msg->lun.pr_res_type = lun->res_type;
> msg->lun.pr_key_count = lun->pr_key_count;
> i = 0;
> if (lun->lun_devid) {
> msg->lun.lun_devid_len = lun->lun_devid->len;
> memcpy(&msg->lun.data[i], lun->lun_devid->data,
> msg->lun.lun_devid_len);
> i += msg->lun.lun_devid_len;
> }
> for (k = 0; k < CTL_MAX_INITIATORS; k++) {
> if ((pr_key.pr_key = ctl_get_prkey(lun, k)) == 0)
> continue;
> pr_key.pr_iid = k;
> memcpy(&msg->lun.data[i], &pr_key, sizeof(pr_key));
> i += sizeof(pr_key);
> }
> mtx_unlock(&lun->lun_lock);
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg->port, sizeof(msg->port) + i,
> M_WAITOK);
> free(msg, M_CTL);
> }
>
> void
> ctl_isc_announce_port(struct ctl_port *port)
> {
> struct ctl_softc *softc = control_softc;
> union ctl_ha_msg *msg;
> int i;
>
> if (port->targ_port < softc->port_min ||
> port->targ_port >= softc->port_max ||
> softc->ha_link != CTL_HA_LINK_ONLINE)
> return;
> i = sizeof(msg->port) + strlen(port->port_name) + 1;
> if (port->lun_map)
> i += sizeof(uint32_t) * CTL_MAX_LUNS;
> if (port->port_devid)
> i += port->port_devid->len;
> if (port->target_devid)
> i += port->target_devid->len;
> msg = malloc(i, M_CTL, M_WAITOK);
> bzero(&msg->port, sizeof(msg->port));
> msg->hdr.msg_type = CTL_MSG_PORT_SYNC;
> msg->hdr.nexus.targ_port = port->targ_port;
> msg->port.port_type = port->port_type;
> msg->port.physical_port = port->physical_port;
> msg->port.virtual_port = port->virtual_port;
> msg->port.status = port->status;
> i = 0;
> msg->port.name_len = sprintf(&msg->port.data[i],
> "%d:%s", softc->ha_id, port->port_name) + 1;
> i += msg->port.name_len;
> if (port->lun_map) {
> msg->port.lun_map_len = sizeof(uint32_t) * CTL_MAX_LUNS;
> memcpy(&msg->port.data[i], port->lun_map,
> msg->port.lun_map_len);
> i += msg->port.lun_map_len;
> }
> if (port->port_devid) {
> msg->port.port_devid_len = port->port_devid->len;
> memcpy(&msg->port.data[i], port->port_devid->data,
> msg->port.port_devid_len);
> i += msg->port.port_devid_len;
> }
> if (port->target_devid) {
> msg->port.target_devid_len = port->target_devid->len;
> memcpy(&msg->port.data[i], port->target_devid->data,
> msg->port.target_devid_len);
> i += msg->port.target_devid_len;
> }
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg->port, sizeof(msg->port) + i,
> M_WAITOK);
> free(msg, M_CTL);
> }
>
> static void
> ctl_isc_ha_link_up(struct ctl_softc *softc)
> {
> struct ctl_port *port;
> struct ctl_lun *lun;
>
> STAILQ_FOREACH(port, &softc->port_list, links)
> ctl_isc_announce_port(port);
> STAILQ_FOREACH(lun, &softc->lun_list, links)
> ctl_isc_announce_lun(lun);
> }
>
> static void
> ctl_isc_ha_link_down(struct ctl_softc *softc)
> {
> struct ctl_port *port;
> struct ctl_lun *lun;
> union ctl_io *io;
>
> mtx_lock(&softc->ctl_lock);
> STAILQ_FOREACH(lun, &softc->lun_list, links) {
> mtx_lock(&lun->lun_lock);
> lun->flags &= ~CTL_LUN_PEER_SC_PRIMARY;
> mtx_unlock(&lun->lun_lock);
>
> mtx_unlock(&softc->ctl_lock);
> io = ctl_alloc_io(softc->othersc_pool);
> mtx_lock(&softc->ctl_lock);
> ctl_zero_io(io);
> io->io_hdr.msg_type = CTL_MSG_FAILOVER;
> io->io_hdr.nexus.targ_mapped_lun = lun->lun;
> ctl_enqueue_isc(io);
> }
>
> STAILQ_FOREACH(port, &softc->port_list, links) {
> if (port->targ_port >= softc->port_min &&
> port->targ_port < softc->port_max)
> continue;
> port->status &= ~CTL_PORT_STATUS_ONLINE;
> }
> mtx_unlock(&softc->ctl_lock);
> }
>
> static void
> ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
> {
> struct ctl_lun *lun;
> uint32_t iid = ctl_get_initindex(&msg->hdr.nexus);
>
> if (msg->hdr.nexus.targ_lun < CTL_MAX_LUNS &&
> (lun = softc->ctl_luns[msg->hdr.nexus.targ_lun]) != NULL) {
> if (msg->ua.ua_all) {
> if (msg->ua.ua_set)
> ctl_est_ua_all(lun, iid, msg->ua.ua_type);
> else
> ctl_clr_ua_all(lun, iid, msg->ua.ua_type);
> } else {
> if (msg->ua.ua_set)
> ctl_est_ua(lun, iid, msg->ua.ua_type);
> else
> ctl_clr_ua(lun, iid, msg->ua.ua_type);
> }
> }
> }
>
> static void
> ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
> {
> struct ctl_lun *lun;
> struct ctl_ha_msg_lun_pr_key pr_key;
> int i, k;
>
> lun = softc->ctl_luns[msg->hdr.nexus.targ_lun];
> if (lun == NULL) {
> CTL_DEBUG_PRINT(("%s: Unknown LUN %d\n", __func__,
> msg->hdr.nexus.targ_lun));
> } else {
> mtx_lock(&lun->lun_lock);
> i = (lun->lun_devid != NULL) ? lun->lun_devid->len : 0;
> if (msg->lun.lun_devid_len != i || (i > 0 &&
> memcmp(&msg->lun.data[0], lun->lun_devid->data, i) != 0)) {
> mtx_unlock(&lun->lun_lock);
> printf("%s: Received conflicting HA LUN %d\n",
> __func__, msg->hdr.nexus.targ_lun);
> return;
> } else {
> /* Record whether peer is primary. */
> if ((msg->lun.flags & CTL_LUN_PRIMARY_SC) &&
> (msg->lun.flags & CTL_LUN_DISABLED) == 0)
> lun->flags |= CTL_LUN_PEER_SC_PRIMARY;
> else
> lun->flags &= ~CTL_LUN_PEER_SC_PRIMARY;
>
> /* If peer is primary and we are not -- use data */
> if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0 &&
> (lun->flags & CTL_LUN_PEER_SC_PRIMARY)) {
> lun->PRGeneration = msg->lun.pr_generation;
> lun->pr_res_idx = msg->lun.pr_res_idx;
> lun->res_type = msg->lun.pr_res_type;
> lun->pr_key_count = msg->lun.pr_key_count;
> for (k = 0; k < CTL_MAX_INITIATORS; k++)
> ctl_clr_prkey(lun, k);
> for (k = 0; k < msg->lun.pr_key_count; k++) {
> memcpy(&pr_key, &msg->lun.data[i],
> sizeof(pr_key));
> ctl_alloc_prkey(lun, pr_key.pr_iid);
> ctl_set_prkey(lun, pr_key.pr_iid,
> pr_key.pr_key);
> i += sizeof(pr_key);
> }
> }
>
> mtx_unlock(&lun->lun_lock);
> CTL_DEBUG_PRINT(("%s: Known LUN %d, peer is %s\n",
> __func__, msg->hdr.nexus.targ_lun,
> (msg->lun.flags & CTL_LUN_PRIMARY_SC) ?
> "primary" : "secondary"));
>
> /* If we are primary but peer doesn't know -- notify */
> if ((lun->flags & CTL_LUN_PRIMARY_SC) &&
> (msg->lun.flags & CTL_LUN_PEER_SC_PRIMARY) == 0)
> ctl_isc_announce_lun(lun);
> }
> }
> }
>
> static void
> ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
> {
> struct ctl_port *port;
> int i, new;
>
> port = softc->ctl_ports[msg->hdr.nexus.targ_port];
> if (port == NULL) {
> CTL_DEBUG_PRINT(("%s: New port %d\n", __func__,
> msg->hdr.nexus.targ_port));
> new = 1;
> port = malloc(sizeof(*port), M_CTL, M_WAITOK | M_ZERO);
> port->frontend = &ha_frontend;
> port->targ_port = msg->hdr.nexus.targ_port;
> } else if (port->frontend == &ha_frontend) {
> CTL_DEBUG_PRINT(("%s: Updated port %d\n", __func__,
> msg->hdr.nexus.targ_port));
> new = 0;
> } else {
> printf("%s: Received conflicting HA port %d\n",
> __func__, msg->hdr.nexus.targ_port);
> return;
> }
> port->port_type = msg->port.port_type;
> port->physical_port = msg->port.physical_port;
> port->virtual_port = msg->port.virtual_port;
> port->status = msg->port.status;
> i = 0;
> free(port->port_name, M_CTL);
> port->port_name = strndup(&msg->port.data[i], msg->port.name_len,
> M_CTL);
> i += msg->port.name_len;
> if (msg->port.lun_map_len != 0) {
> if (port->lun_map == NULL)
> port->lun_map = malloc(sizeof(uint32_t) * CTL_MAX_LUNS,
> M_CTL, M_WAITOK);
> memcpy(port->lun_map, &msg->port.data[i],
> sizeof(uint32_t) * CTL_MAX_LUNS);
> i += msg->port.lun_map_len;
> } else {
> free(port->lun_map, M_CTL);
> port->lun_map = NULL;
> }
> if (msg->port.port_devid_len != 0) {
> if (port->port_devid == NULL ||
> port->port_devid->len != msg->port.port_devid_len) {
> free(port->port_devid, M_CTL);
> port->port_devid = malloc(sizeof(struct ctl_devid) +
> msg->port.port_devid_len, M_CTL, M_WAITOK);
> }
> memcpy(port->port_devid->data, &msg->port.data[i],
> msg->port.port_devid_len);
> port->port_devid->len = msg->port.port_devid_len;
> i += msg->port.port_devid_len;
> } else {
> free(port->port_devid, M_CTL);
> port->port_devid = NULL;
> }
> if (msg->port.target_devid_len != 0) {
> if (port->target_devid == NULL ||
> port->target_devid->len != msg->port.target_devid_len) {
> free(port->target_devid, M_CTL);
> port->target_devid = malloc(sizeof(struct ctl_devid) +
> msg->port.target_devid_len, M_CTL, M_WAITOK);
> }
> memcpy(port->target_devid->data, &msg->port.data[i],
> msg->port.target_devid_len);
> port->target_devid->len = msg->port.target_devid_len;
> i += msg->port.target_devid_len;
> } else {
> free(port->port_devid, M_CTL);
> port->port_devid = NULL;
> }
> if (new) {
> if (ctl_port_register(port) != 0) {
> printf("%s: ctl_port_register() failed with error\n",
> __func__);
> }
> }
> }
>
608,613c876
< io = NULL;
<
<
< #if 0
< printf("CTL: Isc Msg event %d\n", event);
< #endif
---
> CTL_DEBUG_PRINT(("CTL: Isc Msg event %d\n", event));
615c878
< union ctl_ha_msg msg_info;
---
> union ctl_ha_msg *msg, msgbuf;
617,624c880,890
< isc_status = ctl_ha_msg_recv(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), /*wait*/ 0);
< #if 0
< printf("CTL: msg_type %d\n", msg_info.msg_type);
< #endif
< if (isc_status != 0) {
< printf("Error receiving message, status = %d\n",
< isc_status);
---
> if (param > sizeof(msgbuf))
> msg = malloc(param, M_CTL, M_WAITOK);
> else
> msg = &msgbuf;
> isc_status = ctl_ha_msg_recv(CTL_HA_CHAN_CTL, msg, param,
> M_WAITOK);
> if (isc_status != CTL_HA_STATUS_SUCCESS) {
> printf("%s: Error receiving message: %d\n",
> __func__, isc_status);
> if (msg != &msgbuf)
> free(msg, M_CTL);
628c894,895
< switch (msg_info.hdr.msg_type) {
---
> CTL_DEBUG_PRINT(("CTL: msg_type %d\n", msg->msg_type));
> switch (msg->hdr.msg_type) {
630,647c897
< #if 0
< printf("Serialize\n");
< #endif
< io = ctl_alloc_io_nowait(softc->othersc_pool);
< if (io == NULL) {
< printf("ctl_isc_event_handler: can't allocate "
< "ctl_io!\n");
< /* Bad Juju */
< /* Need to set busy and send msg back */
< msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
< msg_info.hdr.status = CTL_SCSI_ERROR;
< msg_info.scsi.scsi_status = SCSI_STATUS_BUSY;
< msg_info.scsi.sense_len = 0;
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0) > CTL_HA_STATUS_SUCCESS){
< }
< goto bailout;
< }
---
> io = ctl_alloc_io(softc->othersc_pool);
649c899
< // populate ctsio from msg_info
---
> // populate ctsio from msg
652,655c902
< io->io_hdr.original_sc = msg_info.hdr.original_sc;
< #if 0
< printf("pOrig %x\n", (int)msg_info.original_sc);
< #endif
---
> io->io_hdr.original_sc = msg->hdr.original_sc;
665c912
< if (softc->ha_mode == CTL_HA_MODE_SER_ONLY)
---
> if (softc->ha_mode != CTL_HA_MODE_XFER)
667c914
< io->io_hdr.nexus = msg_info.hdr.nexus;
---
> io->io_hdr.nexus = msg->hdr.nexus;
674,676c921,928
< io->scsiio.tag_num = msg_info.scsi.tag_num;
< io->scsiio.tag_type = msg_info.scsi.tag_type;
< memcpy(io->scsiio.cdb, msg_info.scsi.cdb,
---
> io->scsiio.tag_num = msg->scsi.tag_num;
> io->scsiio.tag_type = msg->scsi.tag_type;
> #ifdef CTL_TIME_IO
> io->io_hdr.start_time = time_uptime;
> getbintime(&io->io_hdr.start_bt);
> #endif /* CTL_TIME_IO */
> io->scsiio.cdb_len = msg->scsi.cdb_len;
> memcpy(io->scsiio.cdb, msg->scsi.cdb,
694c946
< io = msg_info.hdr.original_sc;
---
> io = msg->hdr.original_sc;
706c958
< io->io_hdr.serializing_sc = msg_info.hdr.serializing_sc;
---
> io->io_hdr.serializing_sc = msg->hdr.serializing_sc;
708,735c960,968
< if (msg_info.dt.sg_sequence == 0) {
< /*
< * XXX KDM we use the preallocated S/G list
< * here, but we'll need to change this to
< * dynamic allocation if we need larger S/G
< * lists.
< */
< if (msg_info.dt.kern_sg_entries >
< sizeof(io->io_hdr.remote_sglist) /
< sizeof(io->io_hdr.remote_sglist[0])) {
< printf("%s: number of S/G entries "
< "needed %u > allocated num %zd\n",
< __func__,
< msg_info.dt.kern_sg_entries,
< sizeof(io->io_hdr.remote_sglist)/
< sizeof(io->io_hdr.remote_sglist[0]));
<
< /*
< * XXX KDM send a message back to
< * the other side to shut down the
< * DMA. The error will come back
< * through via the normal channel.
< */
< break;
< }
< sgl = io->io_hdr.remote_sglist;
< memset(sgl, 0,
< sizeof(io->io_hdr.remote_sglist));
---
> if (msg->dt.sg_sequence == 0) {
> i = msg->dt.kern_sg_entries +
> io->scsiio.kern_data_len /
> CTL_HA_DATAMOVE_SEGMENT + 1;
> sgl = malloc(sizeof(*sgl) * i, M_CTL,
> M_WAITOK | M_ZERO);
> io->io_hdr.remote_sglist = sgl;
> io->io_hdr.local_sglist =
> &sgl[msg->dt.kern_sg_entries];
740c973
< msg_info.dt.kern_sg_entries;
---
> msg->dt.kern_sg_entries;
742c975
< msg_info.dt.kern_sg_entries;
---
> msg->dt.kern_sg_entries;
744c977
< msg_info.dt.kern_data_len;
---
> msg->dt.kern_data_len;
746c979
< msg_info.dt.kern_total_len;
---
> msg->dt.kern_total_len;
748c981
< msg_info.dt.kern_data_resid;
---
> msg->dt.kern_data_resid;
750,760c983,986
< msg_info.dt.kern_rel_offset;
< /*
< * Clear out per-DMA flags.
< */
< io->io_hdr.flags &= ~CTL_FLAG_RDMA_MASK;
< /*
< * Add per-DMA flags that are set for this
< * particular DMA request.
< */
< io->io_hdr.flags |= msg_info.dt.flags &
< CTL_FLAG_RDMA_MASK;
---
> msg->dt.kern_rel_offset;
> io->io_hdr.flags &= ~CTL_FLAG_BUS_ADDR;
> io->io_hdr.flags |= msg->dt.flags &
> CTL_FLAG_BUS_ADDR;
765,769c991,995
< for (i = msg_info.dt.sent_sg_entries, j = 0;
< i < (msg_info.dt.sent_sg_entries +
< msg_info.dt.cur_sg_entries); i++, j++) {
< sgl[i].addr = msg_info.dt.sg_list[j].addr;
< sgl[i].len = msg_info.dt.sg_list[j].len;
---
> for (i = msg->dt.sent_sg_entries, j = 0;
> i < (msg->dt.sent_sg_entries +
> msg->dt.cur_sg_entries); i++, j++) {
> sgl[i].addr = msg->dt.sg_list[j].addr;
> sgl[i].len = msg->dt.sg_list[j].len;
774,775c1000,1001
< msg_info.dt.sg_list[j].addr,
< msg_info.dt.sg_list[j].len,
---
> msg->dt.sg_list[j].addr,
> msg->dt.sg_list[j].len,
779,783d1004
< #if 0
< memcpy(&sgl[msg_info.dt.sent_sg_entries],
< msg_info.dt.sg_list,
< sizeof(*sgl) * msg_info.dt.cur_sg_entries);
< #endif
790c1011
< if (msg_info.dt.sg_last != 0)
---
> if (msg->dt.sg_last != 0)
796c1017
< if (msg_info.hdr.serializing_sc == NULL) {
---
> if (msg->hdr.serializing_sc == NULL) {
807c1028
< io = msg_info.hdr.serializing_sc;
---
> io = msg->hdr.serializing_sc;
809,816c1030,1041
< io->io_hdr.status = msg_info.hdr.status;
< io->scsiio.scsi_status = msg_info.scsi.scsi_status;
< io->scsiio.sense_len = msg_info.scsi.sense_len;
< io->scsiio.sense_residual =msg_info.scsi.sense_residual;
< io->io_hdr.port_status = msg_info.scsi.fetd_status;
< io->scsiio.residual = msg_info.scsi.residual;
< memcpy(&io->scsiio.sense_data,&msg_info.scsi.sense_data,
< sizeof(io->scsiio.sense_data));
---
> io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE;
> io->io_hdr.port_status = msg->scsi.fetd_status;
> io->scsiio.residual = msg->scsi.residual;
> if (msg->hdr.status != CTL_STATUS_NONE) {
> io->io_hdr.status = msg->hdr.status;
> io->scsiio.scsi_status = msg->scsi.scsi_status;
> io->scsiio.sense_len = msg->scsi.sense_len;
> io->scsiio.sense_residual =msg->scsi.sense_residual;
> memcpy(&io->scsiio.sense_data,
> &msg->scsi.sense_data,
> msg->scsi.sense_len);
> }
823c1048
< io = msg_info.hdr.original_sc;
---
> io = msg->hdr.original_sc;
825,830c1050,1052
< printf("%s: Major Bummer\n", __func__);
< return;
< } else {
< #if 0
< printf("pOrig %x\n",(int) ctsio);
< #endif
---
> printf("%s: original_sc == NULL!\n",
> __func__);
> break;
831a1054
> io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE;
833c1056
< io->io_hdr.serializing_sc = msg_info.hdr.serializing_sc;
---
> io->io_hdr.serializing_sc = msg->hdr.serializing_sc;
845,846c1068
< ctl_isc_handler_finish_xfer(softc,
< &msg_info);
---
> ctl_isc_handler_finish_xfer(softc, msg);
848,849c1070
< ctl_isc_handler_finish_ser_only(softc,
< &msg_info);
---
> ctl_isc_handler_finish_ser_only(softc, msg);
854c1075
< io = msg_info.hdr.original_sc;
---
> io = msg->hdr.original_sc;
860c1081
< ctl_copy_sense_data(&msg_info, io);
---
> ctl_copy_sense_data(msg, io);
869c1090
< /* io = msg_info.hdr.serializing_sc; */
---
> /* io = msg->hdr.serializing_sc; */
877c1098
< taskio = (struct ctl_taskio *)ctl_alloc_io_nowait(
---
> taskio = (struct ctl_taskio *)ctl_alloc_io(
879,886d1099
< if (taskio == NULL) {
< printf("ctl_isc_event_handler: can't allocate "
< "ctl_io!\n");
< /* Bad Juju */
< /* should I just call the proper reset func
< here??? */
< goto bailout;
< }
890,893c1103,1106
< taskio->io_hdr.nexus = msg_info.hdr.nexus;
< taskio->task_action = msg_info.task.task_action;
< taskio->tag_num = msg_info.task.tag_num;
< taskio->tag_type = msg_info.task.tag_type;
---
> taskio->io_hdr.nexus = msg->hdr.nexus;
> taskio->task_action = msg->task.task_action;
> taskio->tag_num = msg->task.tag_num;
> taskio->tag_type = msg->task.tag_type;
897,899d1109
< #if 0
< cs_prof_gettime(&taskio->io_hdr.start_ticks);
< #endif
906c1116
< presio = (struct ctl_prio *)ctl_alloc_io_nowait(
---
> presio = (struct ctl_prio *)ctl_alloc_io(
908,914d1117
< if (presio == NULL) {
< printf("ctl_isc_event_handler: can't allocate "
< "ctl_io!\n");
< /* Bad Juju */
< /* Need to set busy and send msg back */
< goto bailout;
< }
917c1120,1122
< presio->pr_msg = msg_info.pr;
---
> presio->io_hdr.flags |= CTL_FLAG_FROM_OTHER_SC;
> presio->io_hdr.nexus = msg->hdr.nexus;
> presio->pr_msg = msg->pr;
920,921c1125,1126
< case CTL_MSG_SYNC_FE:
< rcv_sync_msg = 1;
---
> case CTL_MSG_UA:
> ctl_isc_ua(softc, msg, param);
922a1128,1133
> case CTL_MSG_PORT_SYNC:
> ctl_isc_port_sync(softc, msg, param);
> break;
> case CTL_MSG_LUN_SYNC:
> ctl_isc_lun_sync(softc, msg, param);
> break;
924c1135,1137
< printf("How did I get here?\n");
---
> printf("Received HA message of unknown type %d\n",
> msg->hdr.msg_type);
> break;
926,929c1139,1152
< } else if (event == CTL_HA_EVT_MSG_SENT) {
< if (param != CTL_HA_STATUS_SUCCESS) {
< printf("Bad status from ctl_ha_msg_send status %d\n",
< param);
---
> if (msg != &msgbuf)
> free(msg, M_CTL);
> } else if (event == CTL_HA_EVT_LINK_CHANGE) {
> printf("CTL: HA link status changed from %d to %d\n",
> softc->ha_link, param);
> if (param == softc->ha_link)
> return;
> if (softc->ha_link == CTL_HA_LINK_ONLINE) {
> softc->ha_link = param;
> ctl_isc_ha_link_down(softc);
> } else {
> softc->ha_link = param;
> if (softc->ha_link == CTL_HA_LINK_ONLINE)
> ctl_isc_ha_link_up(softc);
932,934d1154
< } else if (event == CTL_HA_EVT_DISCONNECT) {
< printf("CTL: Got a disconnect from Isc\n");
< return;
939,941d1158
<
< bailout:
< return;
947d1163
< struct scsi_sense_data *sense;
949,950c1165,1166
< sense = &dest->scsiio.sense_data;
< bcopy(&src->scsi.sense_data, sense, sizeof(*sense));
---
> memcpy(&dest->scsiio.sense_data, &src->scsi.sense_data,
> src->scsi.sense_len);
955d1170
< #endif
957a1173,1183
> ctl_copy_sense_data_back(union ctl_io *src, union ctl_ha_msg *dest)
> {
>
> memcpy(&dest->scsi.sense_data, &src->scsiio.sense_data,
> src->scsiio.sense_len);
> dest->scsi.scsi_status = src->scsiio.scsi_status;
> dest->scsi.sense_len = src->scsiio.sense_len;
> dest->hdr.status = src->io_hdr.status;
> }
>
> static void
959a1186
> struct ctl_softc *softc = lun->ctl_softc;
961a1189,1190
> if (initidx < softc->init_min || initidx >= softc->init_max)
> return;
971a1201
> struct ctl_softc *softc = lun->ctl_softc;
975c1205
< for (i = 0; i < CTL_MAX_PORTS; i++) {
---
> for (i = softc->port_min; i < softc->port_max; i++) {
988a1219
> struct ctl_softc *softc = lun->ctl_softc;
990a1222,1223
> if (initidx < softc->init_min || initidx >= softc->init_max)
> return;
1000a1234
> struct ctl_softc *softc = lun->ctl_softc;
1004c1238
< for (i = 0; i < CTL_MAX_PORTS; i++) {
---
> for (i = softc->port_min; i < softc->port_max; i++) {
1030c1264
< ctl_ha_state_sysctl(SYSCTL_HANDLER_ARGS)
---
> ctl_ha_role_sysctl(SYSCTL_HANDLER_ARGS)
1033a1268
> struct ctl_lun_req ireq;
1036,1040c1271
< if (softc->flags & CTL_FLAG_ACTIVE_SHELF)
< value = 0;
< else
< value = 1;
<
---
> value = (softc->flags & CTL_FLAG_ACTIVE_SHELF) ? 0 : 1;
1051,1053c1282,1292
< mtx_lock(&lun->lun_lock);
< ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
< mtx_unlock(&lun->lun_lock);
---
> mtx_unlock(&softc->ctl_lock);
> bzero(&ireq, sizeof(ireq));
> ireq.reqtype = CTL_LUNREQ_MODIFY;
> ireq.reqdata.modify.lun_id = lun->lun;
> lun->backend->ioctl(NULL, CTL_LUN_REQ, (caddr_t)&ireq, 0,
> curthread);
> if (ireq.status != CTL_LUN_OK) {
> printf("%s: CTL_LUNREQ_MODIFY returned %d '%s'\n",
> __func__, ireq.status, ireq.error_str);
> }
> mtx_lock(&softc->ctl_lock);
1065d1303
< //int isc_retval;
1068,1070d1305
< ctl_pause_rtr = 0;
< rcv_sync_msg = 0;
<
1080,1087d1314
< /*
< * By default, return a "bad LUN" peripheral qualifier for unknown
< * LUNs. The user can override this default using the tunable or
< * sysctl. See the comment in ctl_inquiry_std() for more details.
< */
< softc->inquiry_pq_no_lun = 1;
< TUNABLE_INT_FETCH("kern.cam.ctl.inquiry_pq_no_lun",
< &softc->inquiry_pq_no_lun);
1101,1106d1327
< SYSCTL_ADD_INT(&softc->sysctl_ctx,
< SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
< "inquiry_pq_no_lun", CTLFLAG_RW,
< &softc->inquiry_pq_no_lun, 0,
< "Report no lun possible for invalid LUNs");
<
1117a1339,1342
> SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
> OID_AUTO, "ha_mode", CTLFLAG_RDTUN, (int *)&softc->ha_mode, 0,
> "HA mode (0 - act/stby, 1 - serialize only, 2 - xfer)");
>
1126c1351
< if (softc->ha_id == 0) {
---
> if (softc->ha_id == 0 || softc->ha_id > NUM_TARGET_PORT_GROUPS) {
1129,1132c1354,1362
< softc->port_offset = 0;
< } else
< softc->port_offset = (softc->ha_id - 1) * CTL_MAX_PORTS;
< softc->persis_offset = softc->port_offset * CTL_MAX_INIT_PER_PORT;
---
> softc->port_cnt = CTL_MAX_PORTS;
> softc->port_min = 0;
> } else {
> softc->port_cnt = CTL_MAX_PORTS / NUM_TARGET_PORT_GROUPS;
> softc->port_min = (softc->ha_id - 1) * softc->port_cnt;
> }
> softc->port_max = softc->port_min + softc->port_cnt;
> softc->init_min = softc->port_min * CTL_MAX_INIT_PER_PORT;
> softc->init_max = softc->port_max * CTL_MAX_INIT_PER_PORT;
1133a1364,1367
> SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
> OID_AUTO, "ha_link", CTLFLAG_RD, (int *)&softc->ha_link, 0,
> "HA link state (0 - offline, 1 - unknown, 2 - online)");
>
1189,1190c1423,1437
< OID_AUTO, "ha_state", CTLTYPE_INT | CTLFLAG_RWTUN,
< softc, 0, ctl_ha_state_sysctl, "I", "HA state for this head");
---
> OID_AUTO, "ha_role", CTLTYPE_INT | CTLFLAG_RWTUN,
> softc, 0, ctl_ha_role_sysctl, "I", "HA role for this head");
>
> if (softc->is_single == 0) {
> ctl_frontend_register(&ha_frontend);
> if (ctl_ha_msg_init(softc) != CTL_HA_STATUS_SUCCESS) {
> printf("ctl_init: ctl_ha_msg_init failed.\n");
> softc->is_single = 1;
> } else
> if (ctl_ha_msg_register(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
> != CTL_HA_STATUS_SUCCESS) {
> printf("ctl_init: ctl_ha_msg_register failed.\n");
> softc->is_single = 1;
> }
> }
1201a1449,1459
> if (softc->is_single == 0) {
> if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL)
> != CTL_HA_STATUS_SUCCESS) {
> printf("ctl_shutdown: ctl_ha_msg_deregister failed.\n");
> }
> if (ctl_ha_msg_shutdown(softc) != CTL_HA_STATUS_SUCCESS) {
> printf("ctl_shutdown: ctl_ha_msg_shutdown failed.\n");
> }
> ctl_frontend_deregister(&ha_frontend);
> }
>
1261,1320d1518
< int
< ctl_port_enable(ctl_port_type port_type)
< {
< struct ctl_softc *softc = control_softc;
< struct ctl_port *port;
<
< if (softc->is_single == 0) {
< union ctl_ha_msg msg_info;
< int isc_retval;
<
< #if 0
< printf("%s: HA mode, synchronizing frontend enable\n",
< __func__);
< #endif
< msg_info.hdr.msg_type = CTL_MSG_SYNC_FE;
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 1 )) > CTL_HA_STATUS_SUCCESS) {
< printf("Sync msg send error retval %d\n", isc_retval);
< }
< if (!rcv_sync_msg) {
< isc_retval=ctl_ha_msg_recv(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 1);
< }
< #if 0
< printf("CTL:Frontend Enable\n");
< } else {
< printf("%s: single mode, skipping frontend synchronization\n",
< __func__);
< #endif
< }
<
< STAILQ_FOREACH(port, &softc->port_list, links) {
< if (port_type & port->port_type)
< {
< #if 0
< printf("port %d\n", port->targ_port);
< #endif
< ctl_port_online(port);
< }
< }
<
< return (0);
< }
<
< int
< ctl_port_disable(ctl_port_type port_type)
< {
< struct ctl_softc *softc;
< struct ctl_port *port;
<
< softc = control_softc;
<
< STAILQ_FOREACH(port, &softc->port_list, links) {
< if (port_type & port->port_type)
< ctl_port_offline(port);
< }
<
< return (0);
< }
<
1322,1385d1519
< * Returns 0 for success, 1 for failure.
< * Currently the only failure mode is if there aren't enough entries
< * allocated. So, in case of a failure, look at num_entries_dropped,
< * reallocate and try again.
< */
< int
< ctl_port_list(struct ctl_port_entry *entries, int num_entries_alloced,
< int *num_entries_filled, int *num_entries_dropped,
< ctl_port_type port_type, int no_virtual)
< {
< struct ctl_softc *softc;
< struct ctl_port *port;
< int entries_dropped, entries_filled;
< int retval;
< int i;
<
< softc = control_softc;
<
< retval = 0;
< entries_filled = 0;
< entries_dropped = 0;
<
< i = 0;
< mtx_lock(&softc->ctl_lock);
< STAILQ_FOREACH(port, &softc->port_list, links) {
< struct ctl_port_entry *entry;
<
< if ((port->port_type & port_type) == 0)
< continue;
<
< if ((no_virtual != 0)
< && (port->virtual_port != 0))
< continue;
<
< if (entries_filled >= num_entries_alloced) {
< entries_dropped++;
< continue;
< }
< entry = &entries[i];
<
< entry->port_type = port->port_type;
< strlcpy(entry->port_name, port->port_name,
< sizeof(entry->port_name));
< entry->physical_port = port->physical_port;
< entry->virtual_port = port->virtual_port;
< entry->wwnn = port->wwnn;
< entry->wwpn = port->wwpn;
<
< i++;
< entries_filled++;
< }
<
< mtx_unlock(&softc->ctl_lock);
<
< if (entries_dropped > 0)
< retval = 1;
<
< *num_entries_dropped = entries_dropped;
< *num_entries_filled = entries_filled;
<
< return (retval);
< }
<
< /*
1593a1728
> const struct ctl_cmd_entry *entry;
1600,1602c1735,1736
< lun = softc->ctl_luns[targ_lun];
< if (lun==NULL)
< {
---
> if ((targ_lun < CTL_MAX_LUNS) &&
> ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
1603a1738,1750
> * If the LUN is invalid, pretend that it doesn't exist.
> * It will go away as soon as all pending I/O has been
> * completed.
> */
> mtx_lock(&lun->lun_lock);
> if (lun->flags & CTL_LUN_DISABLED) {
> mtx_unlock(&lun->lun_lock);
> lun = NULL;
> }
> } else
> lun = NULL;
> if (lun == NULL) {
> /*
1609,1621c1756,1757
< /* "Logical unit not supported" */
< ctl_set_sense_data(&msg_info.scsi.sense_data,
< lun,
< /*sense_format*/SSD_TYPE_NONE,
< /*current_error*/ 1,
< /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
< /*asc*/ 0x25,
< /*ascq*/ 0x00,
< SSD_ELEM_NONE);
<
< msg_info.scsi.sense_len = SSD_FULL_SIZE;
< msg_info.scsi.scsi_status = SCSI_STATUS_CHECK_COND;
< msg_info.hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
---
> ctl_set_unsupported_lun(ctsio);
> ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
1625,1627c1761,1762
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0 ) > CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi), M_WAITOK);
1628a1764
> }
1629a1766,1775
> entry = ctl_get_cmd_entry(ctsio, NULL);
> if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) {
> mtx_unlock(&lun->lun_lock);
> ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
> msg_info.hdr.original_sc = ctsio->io_hdr.original_sc;
> msg_info.hdr.serializing_sc = NULL;
> msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi), M_WAITOK);
> return(1);
1632,1633c1778,1779
< mtx_lock(&lun->lun_lock);
< TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
---
> ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr = lun;
> ctsio->io_hdr.ctl_private[CTL_PRIV_BACKEND_LUN].ptr = lun->be_lun;
1634a1781,1790
> /*
> * Every I/O goes into the OOA queue for a
> * particular LUN, and stays there until completion.
> */
> #ifdef CTL_TIME_IO
> if (TAILQ_EMPTY(&lun->ooa_queue))
> lun->idle_time += getsbinuptime() - lun->last_busy;
> #endif
> TAILQ_INSERT_TAIL(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
>
1641a1798
> mtx_unlock(&lun->lun_lock);
1647a1805
> mtx_unlock(&lun->lun_lock);
1648a1807,1808
> ctsio->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
> mtx_unlock(&lun->lun_lock);
1654,1659c1814,1815
< #if 0
< printf("2. pOrig %x\n", (int)msg_info.hdr.original_sc);
< #endif
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0 ) > CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.hdr), M_WAITOK);
1663,1671c1819,1821
< /* OVERLAPPED COMMANDS ATTEMPTED */
< ctl_set_sense_data(&msg_info.scsi.sense_data,
< lun,
< /*sense_format*/SSD_TYPE_NONE,
< /*current_error*/ 1,
< /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
< /*asc*/ 0x4E,
< /*ascq*/ 0x00,
< SSD_ELEM_NONE);
---
> TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
> mtx_unlock(&lun->lun_lock);
> retval = 1;
1673,1675c1823,1824
< msg_info.scsi.sense_len = SSD_FULL_SIZE;
< msg_info.scsi.scsi_status = SCSI_STATUS_CHECK_COND;
< msg_info.hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
---
> ctl_set_overlapped_cmd(ctsio);
> ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
1679,1686c1828,1829
< #if 0
< printf("BAD JUJU:Major Bummer Overlap\n");
< #endif
< TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
< retval = 1;
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0 ) > CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi), M_WAITOK);
1689,1701c1832,1836
< /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */
< ctl_set_sense_data(&msg_info.scsi.sense_data,
< lun,
< /*sense_format*/SSD_TYPE_NONE,
< /*current_error*/ 1,
< /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
< /*asc*/ 0x4D,
< /*ascq*/ ctsio->tag_num & 0xff,
< SSD_ELEM_NONE);
<
< msg_info.scsi.sense_len = SSD_FULL_SIZE;
< msg_info.scsi.scsi_status = SCSI_STATUS_CHECK_COND;
< msg_info.hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
---
> TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
> mtx_unlock(&lun->lun_lock);
> retval = 1;
> ctl_set_overlapped_tag(ctsio, ctsio->tag_num);
> ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
1705,1712c1840,1841
< #if 0
< printf("BAD JUJU:Major Bummer Overlap Tag\n");
< #endif
< TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
< retval = 1;
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0 ) > CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi), M_WAITOK);
1716,1724c1845,1847
< /* "Internal target failure" */
< ctl_set_sense_data(&msg_info.scsi.sense_data,
< lun,
< /*sense_format*/SSD_TYPE_NONE,
< /*current_error*/ 1,
< /*sense_key*/ SSD_KEY_HARDWARE_ERROR,
< /*asc*/ 0x44,
< /*ascq*/ 0x00,
< SSD_ELEM_NONE);
---
> TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
> mtx_unlock(&lun->lun_lock);
> retval = 1;
1726,1728c1849,1851
< msg_info.scsi.sense_len = SSD_FULL_SIZE;
< msg_info.scsi.scsi_status = SCSI_STATUS_CHECK_COND;
< msg_info.hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
---
> ctl_set_internal_failure(ctsio, /*sks_valid*/ 0,
> /*retry_count*/ 0);
> ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
1732,1739c1855,1856
< #if 0
< printf("BAD JUJU:Major Bummer HW Error\n");
< #endif
< TAILQ_REMOVE(&lun->ooa_queue, &ctsio->io_hdr, ooa_links);
< retval = 1;
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
< sizeof(msg_info), 0 ) > CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi), M_WAITOK);
1742d1858
< mtx_unlock(&lun->lun_lock);
2002a2119,2122
> if (port->targ_port < softc->port_min ||
> port->targ_port >= softc->port_max)
> continue;
>
2005d2124
<
2035,2043c2154,2155
< if (action != 0) {
< /*
< * XXX KDM we have to drop the lock here,
< * because the online/offline operations
< * can potentially block. We need to
< * reference count the frontends so they
< * can't go away,
< */
< mtx_unlock(&softc->ctl_lock);
---
> if (action == 0)
> continue;
2045,2050c2157,2165
< if (cmd == CTL_ENABLE_PORT) {
< ctl_port_online(port);
< } else if (cmd == CTL_DISABLE_PORT) {
< ctl_port_offline(port);
< }
<
---
> /*
> * XXX KDM we have to drop the lock here, because
> * the online/offline operations can potentially
> * block. We need to reference count the frontends
> * so they can't go away,
> */
> if (cmd == CTL_ENABLE_PORT) {
> mtx_unlock(&softc->ctl_lock);
> ctl_port_online(port);
2052,2058c2167,2176
<
< if (cmd == CTL_SET_PORT_WWNS)
< ctl_port_set_wwns(port,
< (entry->flags & CTL_PORT_WWNN_VALID) ?
< 1 : 0, entry->wwnn,
< (entry->flags & CTL_PORT_WWPN_VALID) ?
< 1 : 0, entry->wwpn);
---
> } else if (cmd == CTL_DISABLE_PORT) {
> mtx_unlock(&softc->ctl_lock);
> ctl_port_offline(port);
> mtx_lock(&softc->ctl_lock);
> } else if (cmd == CTL_SET_PORT_WWNS) {
> ctl_port_set_wwns(port,
> (entry->flags & CTL_PORT_WWNN_VALID) ?
> 1 : 0, entry->wwnn,
> (entry->flags & CTL_PORT_WWPN_VALID) ?
> 1 : 0, entry->wwpn);
2556c2674
< for (j = 0; j < (CTL_MAX_PORTS * 2); j++) {
---
> for (j = 0; j < CTL_MAX_PORTS; j++) {
2848c2966,2969
< retval = fe->ioctl(dev, cmd, addr, flag, td);
---
> if (fe->ioctl)
> retval = fe->ioctl(dev, cmd, addr, flag, td);
> else
> retval = ENODEV;
3007c3128,3129
< if (lm->port >= CTL_MAX_PORTS ||
---
> if (lm->port < softc->port_min ||
> lm->port >= softc->port_max ||
3070,3081d3191
< if (nexus->targ_port < CTL_MAX_PORTS)
< return (nexus->initid +
< (nexus->targ_port * CTL_MAX_INIT_PER_PORT));
< else
< return (nexus->initid +
< ((nexus->targ_port - CTL_MAX_PORTS) *
< CTL_MAX_INIT_PER_PORT));
< }
<
< uint32_t
< ctl_get_resindex(struct ctl_nexus *nexus)
< {
3085,3093d3194
< uint32_t
< ctl_port_idx(int port_num)
< {
< if (port_num < CTL_MAX_PORTS)
< return(port_num);
< else
< return(port_num - CTL_MAX_PORTS);
< }
<
3108,3111c3209,3214
< if (port->status & CTL_PORT_STATUS_ONLINE &&
< port->lun_disable != NULL) {
< STAILQ_FOREACH(lun, &softc->lun_list, links)
< port->lun_disable(port->targ_lun_arg, lun->lun);
---
> if (port->status & CTL_PORT_STATUS_ONLINE) {
> if (port->lun_disable != NULL) {
> STAILQ_FOREACH(lun, &softc->lun_list, links)
> port->lun_disable(port->targ_lun_arg, lun->lun);
> }
> ctl_isc_announce_port(port);
3126,3129c3229,3234
< if (port->status & CTL_PORT_STATUS_ONLINE &&
< port->lun_enable != NULL) {
< STAILQ_FOREACH(lun, &softc->lun_list, links)
< port->lun_enable(port->targ_lun_arg, lun->lun);
---
> if (port->status & CTL_PORT_STATUS_ONLINE) {
> if (port->lun_enable != NULL) {
> STAILQ_FOREACH(lun, &softc->lun_list, links)
> port->lun_enable(port->targ_lun_arg, lun->lun);
> }
> ctl_isc_announce_port(port);
3147,3149c3252,3256
< if ((port->status & CTL_PORT_STATUS_ONLINE) && old >= CTL_MAX_LUNS &&
< port->lun_enable != NULL)
< port->lun_enable(port->targ_lun_arg, plun);
---
> if ((port->status & CTL_PORT_STATUS_ONLINE) && old >= CTL_MAX_LUNS) {
> if (port->lun_enable != NULL)
> port->lun_enable(port->targ_lun_arg, plun);
> ctl_isc_announce_port(port);
> }
3162,3164c3269,3273
< if ((port->status & CTL_PORT_STATUS_ONLINE) && old < CTL_MAX_LUNS &&
< port->lun_disable != NULL)
< port->lun_disable(port->targ_lun_arg, plun);
---
> if ((port->status & CTL_PORT_STATUS_ONLINE) && old < CTL_MAX_LUNS) {
> if (port->lun_disable != NULL)
> port->lun_disable(port->targ_lun_arg, plun);
> ctl_isc_announce_port(port);
> }
3198d3306
< int port_num;
3200,3201c3308
< port_num = io_hdr->nexus.targ_port;
< return (control_softc->ctl_ports[ctl_port_idx(port_num)]);
---
> return (control_softc->ctl_ports[io_hdr->nexus.targ_port]);
3204,3207d3310
< /*
< * Note: This only works for bitmask sizes that are at least 32 bits, and
< * that are a power of 2.
< */
3209c3312
< ctl_ffz(uint32_t *mask, uint32_t size)
---
> ctl_ffz(uint32_t *mask, uint32_t first, uint32_t last)
3211,3212c3314
< uint32_t num_chunks, num_pieces;
< int i, j;
---
> int i;
3214,3223c3316,3318
< num_chunks = (size >> 5);
< if (num_chunks == 0)
< num_chunks++;
< num_pieces = MIN((sizeof(uint32_t) * 8), size);
<
< for (i = 0; i < num_chunks; i++) {
< for (j = 0; j < num_pieces; j++) {
< if ((mask[i] & (1 << j)) == 0)
< return ((i << 5) + j);
< }
---
> for (i = first; i < last; i++) {
> if ((mask[i / 32] & (1 << (i % 32))) == 0)
> return (i);
3225d3319
<
4124c4218
< lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, CTL_MAX_LUNS);
---
> lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, 0, CTL_MAX_LUNS);
4247c4341
< for (i = 0; i < 2 * CTL_MAX_PORTS; i++)
---
> for (i = 0; i < CTL_MAX_PORTS; i++)
4335a4430
> ctl_isc_announce_lun(lun);
4384a4480
> ctl_isc_announce_lun(lun);
4433a4530,4555
> ctl_lun_primary(struct ctl_be_lun *be_lun)
> {
> struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
>
> mtx_lock(&lun->lun_lock);
> lun->flags |= CTL_LUN_PRIMARY_SC;
> mtx_unlock(&lun->lun_lock);
> ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
> ctl_isc_announce_lun(lun);
> return (0);
> }
>
> int
> ctl_lun_secondary(struct ctl_be_lun *be_lun)
> {
> struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
>
> mtx_lock(&lun->lun_lock);
> lun->flags &= ~CTL_LUN_PRIMARY_SC;
> mtx_unlock(&lun->lun_lock);
> ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
> ctl_isc_announce_lun(lun);
> return (0);
> }
>
> int
4497a4620
> union ctl_ha_msg msg;
4501a4625,4638
> if (lun->ctl_softc->ha_mode == CTL_HA_MODE_XFER) {
> /* Send msg to other side. */
> bzero(&msg.ua, sizeof(msg.ua));
> msg.hdr.msg_type = CTL_MSG_UA;
> msg.hdr.nexus.initid = -1;
> msg.hdr.nexus.targ_port = -1;
> msg.hdr.nexus.targ_lun = lun->lun;
> msg.hdr.nexus.targ_mapped_lun = lun->lun;
> msg.ua.ua_all = 1;
> msg.ua.ua_set = 1;
> msg.ua.ua_type = CTL_UA_CAPACITY_CHANGED;
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg.ua),
> M_WAITOK);
> }
4533a4671,4672
> if (ctl_debug & CTL_DEBUG_CDB_DATA)
> ctl_data_print(io);
4560,4561d4698
< if (ctl_debug & CTL_DEBUG_CDB_DATA)
< ctl_data_print(io);
4684c4821
< residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
---
> residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
4774c4911
< residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
---
> residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
4890c5027
< residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
---
> residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
6856c6993
< int alloc_len, ext, total_len = 0, g, p, pc, pg, gs, os;
---
> int alloc_len, ext, total_len = 0, g, pc, pg, gs, os;
6912,6913c7049
< sizeof(struct scsi_target_port_descriptor) *
< num_target_ports * num_target_port_groups;
---
> sizeof(struct scsi_target_port_descriptor) * num_target_ports;
6948,6960c7084,7089
< pg = softc->port_offset / CTL_MAX_PORTS;
< if (softc->flags & CTL_FLAG_ACTIVE_SHELF) {
< if (softc->ha_mode == CTL_HA_MODE_ACT_STBY) {
< gs = TPG_ASYMMETRIC_ACCESS_OPTIMIZED;
< os = TPG_ASYMMETRIC_ACCESS_STANDBY;
< } else if (lun->flags & CTL_LUN_PRIMARY_SC) {
< gs = TPG_ASYMMETRIC_ACCESS_OPTIMIZED;
< os = TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED;
< } else {
< gs = TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED;
< os = TPG_ASYMMETRIC_ACCESS_OPTIMIZED;
< }
< } else {
---
> pg = softc->port_min / softc->port_cnt;
> if (softc->ha_link == CTL_HA_LINK_OFFLINE)
> gs = TPG_ASYMMETRIC_ACCESS_UNAVAILABLE;
> else if (softc->ha_link == CTL_HA_LINK_UNKNOWN)
> gs = TPG_ASYMMETRIC_ACCESS_TRANSITIONING;
> else if (softc->ha_mode == CTL_HA_MODE_ACT_STBY)
6961a7091,7096
> else
> gs = TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED;
> if (lun->flags & CTL_LUN_PRIMARY_SC) {
> os = gs;
> gs = TPG_ASYMMETRIC_ACCESS_OPTIMIZED;
> } else
6963d7097
< }
6966c7100,7101
< tpg_desc->support = TPG_AO_SUP | TPG_AN_SUP | TPG_S_SUP;
---
> tpg_desc->support = TPG_AO_SUP | TPG_AN_SUP | TPG_S_SUP |
> TPG_U_SUP | TPG_T_SUP;
6970a7106,7108
> if (port->targ_port < g * softc->port_cnt ||
> port->targ_port >= (g + 1) * softc->port_cnt)
> continue;
6975,6976c7113
< p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
< scsi_ulto2b(p, tpg_desc->descriptors[pc].
---
> scsi_ulto2b(port->targ_port, tpg_desc->descriptors[pc].
7345c7482
< for (i = 0, key_count = 0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0, key_count = 0; i < CTL_MAX_INITIATORS; i++) {
7474c7611
< for (i = 0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++) {
7488,7489c7625
< port = softc->ctl_ports[
< ctl_port_idx(i / CTL_MAX_INIT_PER_PORT)];
---
> port = softc->ctl_ports[i / CTL_MAX_INIT_PER_PORT];
7519,7527d7654
< static void
< ctl_est_res_ua(struct ctl_lun *lun, uint32_t residx, ctl_ua_type ua)
< {
< int off = lun->ctl_softc->persis_offset;
<
< if (residx >= off && residx < off + CTL_MAX_INITIATORS)
< ctl_est_ua(lun, residx - off, ua);
< }
<
7539,7540c7666
< int retval, i;
< int isc_retval;
---
> int i;
7542,7543d7667
< retval = 0;
<
7577c7701
< for(i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for(i = 0; i < CTL_MAX_INITIATORS; i++) {
7582c7706
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7588a7713,7714
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
7599,7605c7725,7726
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned "
< "from ctl_ha_msg_send %d\n",
< isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
7646c7767
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++) {
7653c7774
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7661a7783,7785
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
>
7671,7676c7795,7796
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
7721c7841
< for(i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for(i = 0; i < CTL_MAX_INITIATORS; i++) {
7728c7848
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7732c7852
< ctl_est_res_ua(lun, i, CTL_UA_RES_RELEASE);
---
> ctl_est_ua(lun, i, CTL_UA_RES_RELEASE);
7740a7861,7862
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
7750,7756c7872,7873
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned "
< "from ctl_ha_msg_send %d\n",
< isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
7764c7881
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++) {
7771c7888
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7780a7898,7900
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
>
7789,7795c7909,7910
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned "
< "from ctl_ha_msg_send %d\n",
< isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
7798,7802c7913
<
< lun->PRGeneration++;
< mtx_unlock(&lun->lun_lock);
<
< return (retval);
---
> return (0);
7821c7932
< for(i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for(i = 0; i < CTL_MAX_INITIATORS; i++) {
7827c7938
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7836c7947
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++) {
7842c7953
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7846c7957
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++) {
7854c7965
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
7858c7969
< ctl_est_res_ua(lun, i, CTL_UA_RES_RELEASE);
---
> ctl_est_ua(lun, i, CTL_UA_RES_RELEASE);
7877d7987
< int isc_retval;
7947c8057
< residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
---
> residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
8062,8064c8172,8173
< for (i = 0; i < CTL_MAX_INITIATORS;i++){
< if (ctl_get_prkey(lun, i +
< softc->persis_offset) == 0)
---
> for (i = softc->init_min; i < softc->init_max; i++){
> if (ctl_get_prkey(lun, i) == 0)
8077a8187,8189
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
>
8082,8087c8194,8195
< if ((isc_retval = ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0 )) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
8097a8206,8207
> lun->PRGeneration++;
> mtx_unlock(&lun->lun_lock);
8106,8111c8216,8217
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
8113,8114d8218
< lun->PRGeneration++;
< mtx_unlock(&lun->lun_lock);
8161,8166c8265,8266
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &persis_io, sizeof(persis_io), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
8210,8213c8310,8311
< for (i = 0; i < CTL_MAX_INITIATORS; i++) {
< if (i == residx ||
< ctl_get_prkey(lun,
< i + softc->persis_offset) == 0)
---
> for (i = softc->init_min; i < softc->init_max; i++) {
> if (i == residx || ctl_get_prkey(lun, i) == 0)
8218a8317
>
8223,8227c8322,8323
< if ((isc_retval=ctl_ha_msg_send( CTL_HA_CHAN_CTL, &persis_io,
< sizeof(persis_io), 0)) > CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
8240c8336
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++)
---
> for (i = 0; i < CTL_MAX_INITIATORS; i++)
8243c8339
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
8246a8343
>
8250,8254c8347,8348
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
< sizeof(persis_io), 0)) > CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Persis Out error returned from "
< "ctl_ha_msg_send %d\n", isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &persis_io,
> sizeof(persis_io.pr), M_WAITOK);
8329,8331c8423,8424
< for (i = 0; i < CTL_MAX_INITIATORS; i++) {
< if (ctl_get_prkey(lun, i +
< softc->persis_offset) == 0)
---
> for (i = softc->init_min; i < softc->init_max; i++) {
> if (ctl_get_prkey(lun, i) == 0)
8362,8363c8455,8456
< for (i = 0; i < CTL_MAX_INITIATORS; i++)
< if (ctl_get_prkey(lun, i + softc->persis_offset) != 0)
---
> for (i = softc->init_min; i < softc->init_max; i++)
> if (ctl_get_prkey(lun, i) != 0)
8381c8474
< for (i=0; i < 2*CTL_MAX_INITIATORS; i++) {
---
> for (i=0; i < CTL_MAX_INITIATORS; i++) {
8385c8478
< ctl_est_res_ua(lun, i, CTL_UA_REG_PREEMPT);
---
> ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
9157,9164d9249
< #ifdef notyet
< static int
< ctl_cmddt_inquiry(struct ctl_scsiio *ctsio)
< {
<
< }
< #endif
<
9440c9525
< port = softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
---
> port = ctl_io_port(&ctsio->io_hdr);
9450c9535
< if (port->port_devid)
---
> if (port && port->port_devid)
9452c9537
< if (port->target_devid)
---
> if (port && port->target_devid)
9484c9569
< if (port->port_type == CTL_PORT_FC)
---
> if (port && port->port_type == CTL_PORT_FC)
9486c9571
< else if (port->port_type == CTL_PORT_ISCSI)
---
> else if (port && port->port_type == CTL_PORT_ISCSI)
9505c9590
< if (port->port_devid) {
---
> if (port && port->port_devid) {
9529c9614
< scsi_ulto2b(ctsio->io_hdr.nexus.targ_port / CTL_MAX_PORTS + 1,
---
> scsi_ulto2b(ctsio->io_hdr.nexus.targ_port / softc->port_cnt + 1,
9537c9622
< if (port->target_devid) {
---
> if (port && port->target_devid) {
9557,9558c9642
< int data_len, num_target_ports, iid_len, id_len, g, pg, p;
< int num_target_port_groups;
---
> int data_len, num_target_ports, iid_len, id_len;
9562,9565d9645
< if (softc->is_single)
< num_target_port_groups = 1;
< else
< num_target_port_groups = NUM_TARGET_PORT_GROUPS;
9584c9664
< data_len = sizeof(struct scsi_vpd_scsi_ports) + num_target_port_groups *
---
> data_len = sizeof(struct scsi_vpd_scsi_ports) +
9621,9649c9701,9725
< pg = softc->port_offset / CTL_MAX_PORTS;
< for (g = 0; g < num_target_port_groups; g++) {
< STAILQ_FOREACH(port, &softc->port_list, links) {
< if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
< continue;
< if (lun != NULL &&
< ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
< continue;
< p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
< scsi_ulto2b(p, pd->relative_port_id);
< if (port->init_devid && g == pg) {
< iid_len = port->init_devid->len;
< memcpy(pd->initiator_transportid,
< port->init_devid->data, port->init_devid->len);
< } else
< iid_len = 0;
< scsi_ulto2b(iid_len, pd->initiator_transportid_length);
< pdc = (struct scsi_vpd_port_designation_cont *)
< (&pd->initiator_transportid[iid_len]);
< if (port->port_devid && g == pg) {
< id_len = port->port_devid->len;
< memcpy(pdc->target_port_descriptors,
< port->port_devid->data, port->port_devid->len);
< } else
< id_len = 0;
< scsi_ulto2b(id_len, pdc->target_port_descriptors_length);
< pd = (struct scsi_vpd_port_designation *)
< ((uint8_t *)pdc->target_port_descriptors + id_len);
< }
---
> STAILQ_FOREACH(port, &softc->port_list, links) {
> if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
> continue;
> if (lun != NULL &&
> ctl_lun_map_to_port(port, lun->lun) >= CTL_MAX_LUNS)
> continue;
> scsi_ulto2b(port->targ_port, pd->relative_port_id);
> if (port->init_devid) {
> iid_len = port->init_devid->len;
> memcpy(pd->initiator_transportid,
> port->init_devid->data, port->init_devid->len);
> } else
> iid_len = 0;
> scsi_ulto2b(iid_len, pd->initiator_transportid_length);
> pdc = (struct scsi_vpd_port_designation_cont *)
> (&pd->initiator_transportid[iid_len]);
> if (port->port_devid) {
> id_len = port->port_devid->len;
> memcpy(pdc->target_port_descriptors,
> port->port_devid->data, port->port_devid->len);
> } else
> id_len = 0;
> scsi_ulto2b(id_len, pdc->target_port_descriptors_length);
> pd = (struct scsi_vpd_port_designation *)
> ((uint8_t *)pdc->target_port_descriptors + id_len);
9915a9992
> struct ctl_port *port;
9928,9929c10005,10009
< port_type = softc->ctl_ports[
< ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]->port_type;
---
> port = ctl_io_port(&ctsio->io_hdr);
> if (port != NULL)
> port_type = port->port_type;
> else
> port_type = CTL_PORT_SCSI;
9959,10007c10039,10048
< /*
< * If we have a LUN configured, report it as connected. Otherwise,
< * report that it is offline or no device is supported, depending
< * on the value of inquiry_pq_no_lun.
< *
< * According to the spec (SPC-4 r34), the peripheral qualifier
< * SID_QUAL_LU_OFFLINE (001b) is used in the following scenario:
< *
< * "A peripheral device having the specified peripheral device type
< * is not connected to this logical unit. However, the device
< * server is capable of supporting the specified peripheral device
< * type on this logical unit."
< *
< * According to the same spec, the peripheral qualifier
< * SID_QUAL_BAD_LU (011b) is used in this scenario:
< *
< * "The device server is not capable of supporting a peripheral
< * device on this logical unit. For this peripheral qualifier the
< * peripheral device type shall be set to 1Fh. All other peripheral
< * device type values are reserved for this peripheral qualifier."
< *
< * Given the text, it would seem that we probably want to report that
< * the LUN is offline here. There is no LUN connected, but we can
< * support a LUN at the given LUN number.
< *
< * In the real world, though, it sounds like things are a little
< * different:
< *
< * - Linux, when presented with a LUN with the offline peripheral
< * qualifier, will create an sg driver instance for it. So when
< * you attach it to CTL, you wind up with a ton of sg driver
< * instances. (One for every LUN that Linux bothered to probe.)
< * Linux does this despite the fact that it issues a REPORT LUNs
< * to LUN 0 to get the inventory of supported LUNs.
< *
< * - There is other anecdotal evidence (from Emulex folks) about
< * arrays that use the offline peripheral qualifier for LUNs that
< * are on the "passive" path in an active/passive array.
< *
< * So the solution is provide a hopefully reasonable default
< * (return bad/no LUN) and allow the user to change the behavior
< * with a tunable/sysctl variable.
< */
< if (lun != NULL)
< inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
< lun->be_lun->lun_type;
< else if (softc->inquiry_pq_no_lun == 0)
< inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
< else
---
> if (lun != NULL) {
> if ((lun->flags & CTL_LUN_PRIMARY_SC) ||
> softc->ha_link >= CTL_HA_LINK_UNKNOWN) {
> inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
> lun->be_lun->lun_type;
> } else {
> inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) |
> lun->be_lun->lun_type;
> }
> } else
10596a10638
> struct ctl_softc *softc = lun->ctl_softc;
10642d10683
< int isc_retval;
10658c10699,10700
< if (cur_blocked->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC){
---
> if ((softc->ha_mode != CTL_HA_MODE_XFER) &&
> (cur_blocked->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)){
10664a10707
> cur_blocked->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
10669,10675c10712,10713
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< &msg_info, sizeof(msg_info), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:Check Blocked error from "
< "ctl_ha_msg_send %d\n",
< isc_retval);
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.hdr), M_NOWAIT);
10734,10735c10772,10773
< * If this shelf is a secondary shelf controller, we have to reject
< * any media access commands.
---
> * If this shelf is a secondary shelf controller, we may have to
> * reject some commands disallowed by HA mode and link state.
10737,10741c10775,10797
< if ((softc->flags & CTL_FLAG_ACTIVE_SHELF) == 0 &&
< (entry->flags & CTL_CMD_FLAG_OK_ON_SECONDARY) == 0) {
< ctl_set_lun_standby(ctsio);
< retval = 1;
< goto bailout;
---
> if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0) {
> if (softc->ha_link == CTL_HA_LINK_OFFLINE &&
> (entry->flags & CTL_CMD_FLAG_OK_ON_UNAVAIL) == 0) {
> ctl_set_lun_unavail(ctsio);
> retval = 1;
> goto bailout;
> }
> if ((lun->flags & CTL_LUN_PEER_SC_PRIMARY) == 0 &&
> (entry->flags & CTL_CMD_FLAG_OK_ON_UNAVAIL) == 0) {
> ctl_set_lun_transit(ctsio);
> retval = 1;
> goto bailout;
> }
> if (softc->ha_mode == CTL_HA_MODE_ACT_STBY &&
> (entry->flags & CTL_CMD_FLAG_OK_ON_STANDBY) == 0) {
> ctl_set_lun_standby(ctsio);
> retval = 1;
> goto bailout;
> }
>
> /* The rest of checks are only done on executing side */
> if (softc->ha_mode == CTL_HA_MODE_XFER)
> goto bailout;
10768c10824
< residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
---
> residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
10798d10853
<
10802c10857
< && ((entry->flags & CTL_CMD_FLAG_OK_ON_OFFLINE) == 0)) {
---
> && ((entry->flags & CTL_CMD_FLAG_OK_ON_STANDBY) == 0)) {
10808,10811d10862
< /*
< * If the LUN is stopped, see if this particular command is allowed
< * for a stopped lun. Otherwise, reject it with 0x04,0x02.
< */
10830d10880
<
10840d10889
< #ifdef notyet
10842c10891
< ctl_failover(void)
---
> ctl_failover_lun(struct ctl_lun *lun)
10844,10848c10893,10894
< struct ctl_lun *lun;
< struct ctl_softc *softc;
< union ctl_io *next_io, *pending_io;
< union ctl_io *io;
< int lun_idx;
---
> struct ctl_softc *softc = lun->ctl_softc;
> struct ctl_io_hdr *io, *next_io;
10850,10907c10896,10907
< softc = control_softc;
<
< mtx_lock(&softc->ctl_lock);
< /*
< * Remove any cmds from the other SC from the rtr queue. These
< * will obviously only be for LUNs for which we're the primary.
< * We can't send status or get/send data for these commands.
< * Since they haven't been executed yet, we can just remove them.
< * We'll either abort them or delete them below, depending on
< * which HA mode we're in.
< */
< #ifdef notyet
< mtx_lock(&softc->queue_lock);
< for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue);
< io != NULL; io = next_io) {
< next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links);
< if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)
< STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr,
< ctl_io_hdr, links);
< }
< mtx_unlock(&softc->queue_lock);
< #endif
<
< for (lun_idx=0; lun_idx < softc->num_luns; lun_idx++) {
< lun = softc->ctl_luns[lun_idx];
< if (lun==NULL)
< continue;
<
< /*
< * Processor LUNs are primary on both sides.
< * XXX will this always be true?
< */
< if (lun->be_lun->lun_type == T_PROCESSOR)
< continue;
<
< if ((lun->flags & CTL_LUN_PRIMARY_SC)
< && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
< printf("FAILOVER: primary lun %d\n", lun_idx);
< /*
< * Remove all commands from the other SC. First from the
< * blocked queue then from the ooa queue. Once we have
< * removed them. Call ctl_check_blocked to see if there
< * is anything that can run.
< */
< for (io = (union ctl_io *)TAILQ_FIRST(
< &lun->blocked_queue); io != NULL; io = next_io) {
<
< next_io = (union ctl_io *)TAILQ_NEXT(
< &io->io_hdr, blocked_links);
<
< if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) {
< TAILQ_REMOVE(&lun->blocked_queue,
< &io->io_hdr,blocked_links);
< io->io_hdr.flags &= ~CTL_FLAG_BLOCKED;
< TAILQ_REMOVE(&lun->ooa_queue,
< &io->io_hdr, ooa_links);
<
< ctl_free_io(io);
---
> CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", lun->lun));
> if (softc->ha_mode == CTL_HA_MODE_XFER) {
> TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) {
> /* We are master */
> if (io->flags & CTL_FLAG_FROM_OTHER_SC) {
> if (io->flags & CTL_FLAG_IO_ACTIVE) {
> io->flags |= CTL_FLAG_ABORT;
> } else { /* This can be only due to DATAMOVE */
> io->msg_type = CTL_MSG_DATAMOVE_DONE;
> io->flags |= CTL_FLAG_IO_ACTIVE;
> io->port_status = 31340;
> ctl_enqueue_isc((union ctl_io *)io);
10910,10976c10910,10914
<
< for (io = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue);
< io != NULL; io = next_io) {
<
< next_io = (union ctl_io *)TAILQ_NEXT(
< &io->io_hdr, ooa_links);
<
< if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) {
<
< TAILQ_REMOVE(&lun->ooa_queue,
< &io->io_hdr,
< ooa_links);
<
< ctl_free_io(io);
< }
< }
< ctl_check_blocked(lun);
< } else if ((lun->flags & CTL_LUN_PRIMARY_SC)
< && (softc->ha_mode == CTL_HA_MODE_XFER)) {
<
< printf("FAILOVER: primary lun %d\n", lun_idx);
< /*
< * Abort all commands from the other SC. We can't
< * send status back for them now. These should get
< * cleaned up when they are completed or come out
< * for a datamove operation.
< */
< for (io = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue);
< io != NULL; io = next_io) {
< next_io = (union ctl_io *)TAILQ_NEXT(
< &io->io_hdr, ooa_links);
<
< if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)
< io->io_hdr.flags |= CTL_FLAG_ABORT;
< }
< } else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0)
< && (softc->ha_mode == CTL_HA_MODE_XFER)) {
<
< printf("FAILOVER: secondary lun %d\n", lun_idx);
<
< lun->flags |= CTL_LUN_PRIMARY_SC;
<
< /*
< * We send all I/O that was sent to this controller
< * and redirected to the other side back with
< * busy status, and have the initiator retry it.
< * Figuring out how much data has been transferred,
< * etc. and picking up where we left off would be
< * very tricky.
< *
< * XXX KDM need to remove I/O from the blocked
< * queue as well!
< */
< for (pending_io = (union ctl_io *)TAILQ_FIRST(
< &lun->ooa_queue); pending_io != NULL;
< pending_io = next_io) {
<
< next_io = (union ctl_io *)TAILQ_NEXT(
< &pending_io->io_hdr, ooa_links);
<
< pending_io->io_hdr.flags &=
< ~CTL_FLAG_SENT_2OTHER_SC;
<
< if (pending_io->io_hdr.flags &
< CTL_FLAG_IO_ACTIVE) {
< pending_io->io_hdr.flags |=
< CTL_FLAG_FAILOVER;
---
> /* We are slave */
> if (io->flags & CTL_FLAG_SENT_2OTHER_SC) {
> io->flags &= ~CTL_FLAG_SENT_2OTHER_SC;
> if (io->flags & CTL_FLAG_IO_ACTIVE) {
> io->flags |= CTL_FLAG_FAILOVER;
10978,10979c10916,10918
< ctl_set_busy(&pending_io->scsiio);
< ctl_done(pending_io);
---
> ctl_set_busy(&((union ctl_io *)io)->
> scsiio);
> ctl_done((union ctl_io *)io);
10982,10997c10921,10931
<
< ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
< } else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0)
< && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
< printf("FAILOVER: secondary lun %d\n", lun_idx);
< /*
< * if the first io on the OOA is not on the RtR queue
< * add it.
< */
< lun->flags |= CTL_LUN_PRIMARY_SC;
<
< pending_io = (union ctl_io *)TAILQ_FIRST(
< &lun->ooa_queue);
< if (pending_io==NULL) {
< printf("Nothing on OOA queue\n");
< continue;
---
> }
> } else { /* SERIALIZE modes */
> TAILQ_FOREACH_SAFE(io, &lun->blocked_queue, blocked_links,
> next_io) {
> /* We are master */
> if (io->flags & CTL_FLAG_FROM_OTHER_SC) {
> TAILQ_REMOVE(&lun->blocked_queue, io,
> blocked_links);
> io->flags &= ~CTL_FLAG_BLOCKED;
> TAILQ_REMOVE(&lun->ooa_queue, io, ooa_links);
> ctl_free_io((union ctl_io *)io);
10999,11005c10933,10938
<
< pending_io->io_hdr.flags &= ~CTL_FLAG_SENT_2OTHER_SC;
< if ((pending_io->io_hdr.flags &
< CTL_FLAG_IS_WAS_ON_RTR) == 0) {
< pending_io->io_hdr.flags |=
< CTL_FLAG_IS_WAS_ON_RTR;
< ctl_enqueue_rtr(pending_io);
---
> }
> TAILQ_FOREACH_SAFE(io, &lun->ooa_queue, ooa_links, next_io) {
> /* We are master */
> if (io->flags & CTL_FLAG_FROM_OTHER_SC) {
> TAILQ_REMOVE(&lun->ooa_queue, io, ooa_links);
> ctl_free_io((union ctl_io *)io);
11007,11029c10940,10946
< #if 0
< else
< {
< printf("Tag 0x%04x is running\n",
< pending_io->scsiio.tag_num);
< }
< #endif
<
< next_io = (union ctl_io *)TAILQ_NEXT(
< &pending_io->io_hdr, ooa_links);
< for (pending_io=next_io; pending_io != NULL;
< pending_io = next_io) {
< pending_io->io_hdr.flags &=
< ~CTL_FLAG_SENT_2OTHER_SC;
< next_io = (union ctl_io *)TAILQ_NEXT(
< &pending_io->io_hdr, ooa_links);
< if (pending_io->io_hdr.flags &
< CTL_FLAG_IS_WAS_ON_RTR) {
< #if 0
< printf("Tag 0x%04x is running\n",
< pending_io->scsiio.tag_num);
< #endif
< continue;
---
> /* We are slave */
> if (io->flags & CTL_FLAG_SENT_2OTHER_SC) {
> io->flags &= ~CTL_FLAG_SENT_2OTHER_SC;
> if (!(io->flags & CTL_FLAG_IO_ACTIVE)) {
> ctl_set_busy(&((union ctl_io *)io)->
> scsiio);
> ctl_done((union ctl_io *)io);
11031,11069d10947
<
< switch (ctl_check_ooa(lun, pending_io,
< (union ctl_io *)TAILQ_PREV(
< &pending_io->io_hdr, ctl_ooaq,
< ooa_links))) {
<
< case CTL_ACTION_BLOCK:
< TAILQ_INSERT_TAIL(&lun->blocked_queue,
< &pending_io->io_hdr,
< blocked_links);
< pending_io->io_hdr.flags |=
< CTL_FLAG_BLOCKED;
< break;
< case CTL_ACTION_PASS:
< case CTL_ACTION_SKIP:
< pending_io->io_hdr.flags |=
< CTL_FLAG_IS_WAS_ON_RTR;
< ctl_enqueue_rtr(pending_io);
< break;
< case CTL_ACTION_OVERLAP:
< ctl_set_overlapped_cmd(
< (struct ctl_scsiio *)pending_io);
< ctl_done(pending_io);
< break;
< case CTL_ACTION_OVERLAP_TAG:
< ctl_set_overlapped_tag(
< (struct ctl_scsiio *)pending_io,
< pending_io->scsiio.tag_num & 0xff);
< ctl_done(pending_io);
< break;
< case CTL_ACTION_ERROR:
< default:
< ctl_set_internal_failure(
< (struct ctl_scsiio *)pending_io,
< 0, // sks_valid
< 0); //retry count
< ctl_done(pending_io);
< break;
< }
11071,11075d10948
<
< ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
< } else {
< panic("Unhandled HA mode failover, LUN flags = %#x, "
< "ha_mode = #%x", lun->flags, softc->ha_mode);
11076a10950
> ctl_check_blocked(lun);
11078,11079d10951
< ctl_pause_rtr = 0;
< mtx_unlock(&softc->ctl_lock);
11081d10952
< #endif
11113,11115d10983
< if (lun->be_lun->lun_type == T_PROCESSOR) {
< ctsio->io_hdr.flags |= CTL_FLAG_CONTROL_DEV;
< }
11250c11118,11119
< if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0) {
---
> if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0 &&
> (lun->flags & CTL_LUN_PEER_SC_PRIMARY) != 0) {
11254a11124,11125
> ctsio->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
> mtx_unlock(&lun->lun_lock);
11258,11260d11128
< #if 0
< printf("1. ctsio %p\n", ctsio);
< #endif
11264a11133
> msg_info.scsi.cdb_len = ctsio->cdb_len;
11267,11278c11136,11141
< ctsio->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
<
< if ((isc_retval=ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< (void *)&msg_info, sizeof(msg_info), 0)) >
< CTL_HA_STATUS_SUCCESS) {
< printf("CTL:precheck, ctl_ha_msg_send returned %d\n",
< isc_retval);
< printf("CTL:opcode is %x\n", ctsio->cdb[0]);
< } else {
< #if 0
< printf("CTL:Precheck sent msg, opcode is %x\n",opcode);
< #endif
---
> if ((isc_retval = ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.scsi) - sizeof(msg_info.scsi.sense_data),
> M_WAITOK)) > CTL_HA_STATUS_SUCCESS) {
> ctl_set_busy(ctsio);
> ctl_done((union ctl_io *)ctsio);
> return (retval);
11280,11288d11142
<
< /*
< * XXX KDM this I/O is off the incoming queue, but hasn't
< * been inserted on any other queue. We may need to come
< * up with a holding queue while we wait for serialization
< * so that we have an idea of what we're waiting for from
< * the other side.
< */
< mtx_unlock(&lun->lun_lock);
11458d11311
< io->io_hdr.flags |= CTL_FLAG_SENT_2OTHER_SC;
11467,11469c11320,11321
< if (CTL_HA_STATUS_SUCCESS != ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< (void *)&msg_info, sizeof(msg_info), 0)) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.task), M_WAITOK);
11587,11588c11439,11440
< ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< (void *)&msg_info, sizeof(msg_info), 0);
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.task), M_NOWAIT);
11632c11484
< uint32_t initidx, residx;
---
> uint32_t initidx;
11635d11486
< residx = ctl_get_resindex(&io->io_hdr.nexus);
11645c11496
< if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == residx))
---
> if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx))
11750d11600
< io->io_hdr.flags |= CTL_FLAG_SENT_2OTHER_SC;
11761,11764c11611,11612
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< (void *)&msg_info, sizeof(msg_info), 0) !=
< CTL_HA_STATUS_SUCCESS) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.task), M_NOWAIT);
11857a11706,11707
> retval = ctl_lun_reset(lun, io, CTL_UA_LUN_RESET);
> mtx_unlock(&softc->ctl_lock);
11859,11860c11709
< if (!(io->io_hdr.flags &
< CTL_FLAG_FROM_OTHER_SC)) {
---
> if ((io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) == 0) {
11863,11866c11712
< io->io_hdr.flags |=
< CTL_FLAG_SENT_2OTHER_SC;
< msg_info.hdr.msg_type =
< CTL_MSG_MANAGE_TASKS;
---
> msg_info.hdr.msg_type = CTL_MSG_MANAGE_TASKS;
11868,11869c11714
< msg_info.task.task_action =
< CTL_TASK_LUN_RESET;
---
> msg_info.task.task_action = CTL_TASK_LUN_RESET;
11872,11876c11717,11718
< if (CTL_HA_STATUS_SUCCESS !=
< ctl_ha_msg_send(CTL_HA_CHAN_CTL,
< (void *)&msg_info,
< sizeof(msg_info), 0)) {
< }
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
> sizeof(msg_info.task), M_WAITOK);
11878,11881d11719
<
< retval = ctl_lun_reset(lun, io,
< CTL_UA_LUN_RESET);
< mtx_unlock(&softc->ctl_lock);
11978a11817,11822
> case CTL_MSG_FAILOVER:
> mtx_lock(&lun->lun_lock);
> ctl_failover_lun(lun);
> mtx_unlock(&lun->lun_lock);
> free_io = 1;
> break;
12180,12183d12023
< struct ctl_lun *lun;
<
< lun =(struct ctl_lun *)io->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
<
12259a12100
> #if 0
12261,12275d12101
< * If this is in cached memory, flush the cache
< * before we send the DMA request to the other
< * controller. We want to do this in either the
< * read or the write case. The read case is
< * straightforward. In the write case, we want to
< * make sure nothing is in the local cache that
< * could overwrite the DMAed data.
< */
< if ((io->io_hdr.flags & CTL_FLAG_NO_DATASYNC) == 0) {
< /*
< * XXX KDM use bus_dmamap_sync() here.
< */
< }
<
< /*
12286d12111
< #if 0
12289d12113
< #endif
12290a12115,12119
> #else
> KASSERT((io->io_hdr.flags & CTL_FLAG_BUS_ADDR) == 0,
> ("HA does not support BUS_ADDR"));
> msg.dt.sg_list[0].addr = io->scsiio.kern_data_ptr;
> #endif
12295,12297d12123
< struct ctl_sg_entry *sgl;
<
< do_sg_copy = 1;
12299,12304c12125
< sgl = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
< if ((io->io_hdr.flags & CTL_FLAG_NO_DATASYNC) == 0) {
< /*
< * XXX KDM use bus_dmamap_sync() here.
< */
< }
---
> do_sg_copy = 1;
12342a12164
> #if 0
12344,12349d12165
< CTL_FLAG_NO_DATASYNC) == 0) {
< /*
< * XXX KDM use bus_dmamap_sync()
< */
< }
< if ((io->io_hdr.flags &
12354d12169
< #if 0
12357d12171
< #endif
12361a12176,12181
> #else
> KASSERT((io->io_hdr.flags &
> CTL_FLAG_BUS_ADDR) == 0,
> ("HA does not support BUS_ADDR"));
> msg.dt.sg_list[j].addr = sgl[i].addr;
> #endif
12372,12374d12191
< /*
< * XXX KDM drop and reacquire the lock here?
< */
12376,12379c12193,12198
< sizeof(msg), 0) > CTL_HA_STATUS_SUCCESS) {
< /*
< * XXX do something here.
< */
---
> sizeof(msg.dt) - sizeof(msg.dt.sg_list) +
> sizeof(struct ctl_sg_entry)*msg.dt.cur_sg_entries,
> M_WAITOK) > CTL_HA_STATUS_SUCCESS) {
> io->io_hdr.port_status = 31341;
> io->scsiio.be_move_done(io);
> return;
12385,12387d12203
< if (io->io_hdr.flags & CTL_FLAG_FAILOVER)
< ctl_failover_io(io, /*have_lock*/ 0);
<
12394,12395c12210
< fe_datamove =
< control_softc->ctl_ports[ctl_port_idx(io->io_hdr.nexus.targ_port)]->fe_datamove;
---
> fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
12405d12219
< int isc_status;
12418c12232
< sizeof(io->scsiio.sense_data));
---
> io->scsiio.sense_len);
12430,12434c12244,12246
< isc_status = ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg), 0);
< if (isc_status > CTL_HA_STATUS_SUCCESS) {
< /* XXX do something if this fails */
< }
<
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
> sizeof(msg.scsi) - sizeof(msg.scsi.sense_data) +
> msg.scsi.sense_len, M_WAITOK);
12444a12257
> int i;
12457a12271,12276
> for (i = 0; i < io->scsiio.kern_sg_entries; i++)
> free(io->io_hdr.local_sglist[i].addr, M_CTL);
> free(io->io_hdr.remote_sglist, M_CTL);
> io->io_hdr.remote_sglist = NULL;
> io->io_hdr.local_sglist = NULL;
>
12459,12466d12277
< * In this case, we had to malloc the memory locally. Free it.
< */
< if ((io->io_hdr.flags & CTL_FLAG_AUTO_MIRROR) == 0) {
< int i;
< for (i = 0; i < io->scsiio.kern_sg_entries; i++)
< free(io->io_hdr.local_sglist[i].addr, M_CTL);
< }
< /*
12515c12326
< fe_datamove = control_softc->ctl_ports[ctl_port_idx(io->io_hdr.nexus.targ_port)]->fe_datamove;
---
> fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
12530a12342
> int i;
12532,12539c12344,12348
< /*
< * In this case, we had to malloc the memory locally. Free it.
< */
< if ((io->io_hdr.flags & CTL_FLAG_AUTO_MIRROR) == 0) {
< int i;
< for (i = 0; i < io->scsiio.kern_sg_entries; i++)
< free(io->io_hdr.local_sglist[i].addr, M_CTL);
< }
---
> for (i = 0; i < io->scsiio.kern_sg_entries; i++)
> free(io->io_hdr.local_sglist[i].addr, M_CTL);
> free(io->io_hdr.remote_sglist, M_CTL);
> io->io_hdr.remote_sglist = NULL;
> io->io_hdr.local_sglist = NULL;
12576c12385
< printf("%s: ISC DMA read failed with error %d", __func__,
---
> printf("%s: ISC DMA read failed with error %d\n", __func__,
12596c12405
< fe_datamove = control_softc->ctl_ports[ctl_port_idx(io->io_hdr.nexus.targ_port)]->fe_datamove;
---
> fe_datamove = ctl_io_port(&io->io_hdr)->fe_datamove;
12605d12413
< struct ctl_sg_entry *local_dma_sglist, *remote_dma_sglist;
12606a12415
> uint32_t len_to_go;
12612d12420
<
12614d12421
< local_dma_sglist = io->io_hdr.local_dma_sglist;
12616c12423
< remote_dma_sglist = io->io_hdr.remote_dma_sglist;
---
> len_to_go = io->scsiio.kern_data_len;
12618,12620c12425,12434
< if (io->io_hdr.flags & CTL_FLAG_AUTO_MIRROR) {
< for (i = 0; i < io->scsiio.kern_sg_entries; i++) {
< local_sglist[i].len = remote_sglist[i].len;
---
> /*
> * The difficult thing here is that the size of the various
> * S/G segments may be different than the size from the
> * remote controller. That'll make it harder when DMAing
> * the data back to the other side.
> */
> for (i = 0; len_to_go > 0; i++) {
> local_sglist[i].len = MIN(len_to_go, CTL_HA_DATAMOVE_SEGMENT);
> local_sglist[i].addr =
> malloc(local_sglist[i].len, M_CTL, M_WAITOK);
12622,12657c12436,12442
< /*
< * XXX Detect the situation where the RS-level I/O
< * redirector on the other side has already read the
< * data off of the AOR RS on this side, and
< * transferred it to remote (mirror) memory on the
< * other side. Since we already have the data in
< * memory here, we just need to use it.
< *
< * XXX KDM this can probably be removed once we
< * get the cache device code in and take the
< * current AOR implementation out.
< */
< #ifdef NEEDTOPORT
< if ((remote_sglist[i].addr >=
< (void *)vtophys(softc->mirr->addr))
< && (remote_sglist[i].addr <
< ((void *)vtophys(softc->mirr->addr) +
< CacheMirrorOffset))) {
< local_sglist[i].addr = remote_sglist[i].addr -
< CacheMirrorOffset;
< if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
< CTL_FLAG_DATA_IN)
< io->io_hdr.flags |= CTL_FLAG_REDIR_DONE;
< } else {
< local_sglist[i].addr = remote_sglist[i].addr +
< CacheMirrorOffset;
< }
< #endif
< #if 0
< printf("%s: local %p, remote %p, len %d\n",
< __func__, local_sglist[i].addr,
< remote_sglist[i].addr, local_sglist[i].len);
< #endif
< }
< } else {
< uint32_t len_to_go;
---
> len_to_go -= local_sglist[i].len;
> }
> /*
> * Reset the number of S/G entries accordingly. The original
> * number of S/G entries is available in rem_sg_entries.
> */
> io->scsiio.kern_sg_entries = i;
12659,12716d12443
< /*
< * In this case, we don't have automatically allocated
< * memory for this I/O on this controller. This typically
< * happens with internal CTL I/O -- e.g. inquiry, mode
< * sense, etc. Anything coming from RAIDCore will have
< * a mirror area available.
< */
< len_to_go = io->scsiio.kern_data_len;
<
< /*
< * Clear the no datasync flag, we have to use malloced
< * buffers.
< */
< io->io_hdr.flags &= ~CTL_FLAG_NO_DATASYNC;
<
< /*
< * The difficult thing here is that the size of the various
< * S/G segments may be different than the size from the
< * remote controller. That'll make it harder when DMAing
< * the data back to the other side.
< */
< for (i = 0; (i < sizeof(io->io_hdr.remote_sglist) /
< sizeof(io->io_hdr.remote_sglist[0])) &&
< (len_to_go > 0); i++) {
< local_sglist[i].len = MIN(len_to_go, 131072);
< CTL_SIZE_8B(local_dma_sglist[i].len,
< local_sglist[i].len);
< local_sglist[i].addr =
< malloc(local_dma_sglist[i].len, M_CTL,M_WAITOK);
<
< local_dma_sglist[i].addr = local_sglist[i].addr;
<
< if (local_sglist[i].addr == NULL) {
< int j;
<
< printf("malloc failed for %zd bytes!",
< local_dma_sglist[i].len);
< for (j = 0; j < i; j++) {
< free(local_sglist[j].addr, M_CTL);
< }
< ctl_set_internal_failure(&io->scsiio,
< /*sks_valid*/ 1,
< /*retry_count*/ 4857);
< retval = 1;
< goto bailout_error;
<
< }
< /* XXX KDM do we need a sync here? */
<
< len_to_go -= local_sglist[i].len;
< }
< /*
< * Reset the number of S/G entries accordingly. The
< * original number of S/G entries is available in
< * rem_sg_entries.
< */
< io->scsiio.kern_sg_entries = i;
<
12718,12723c12445,12449
< printf("%s: kern_sg_entries = %d\n", __func__,
< io->scsiio.kern_sg_entries);
< for (i = 0; i < io->scsiio.kern_sg_entries; i++)
< printf("%s: sg[%d] = %p, %d (DMA: %d)\n", __func__, i,
< local_sglist[i].addr, local_sglist[i].len,
< local_dma_sglist[i].len);
---
> printf("%s: kern_sg_entries = %d\n", __func__,
> io->scsiio.kern_sg_entries);
> for (i = 0; i < io->scsiio.kern_sg_entries; i++)
> printf("%s: sg[%d] = %p, %d\n", __func__, i,
> local_sglist[i].addr, local_sglist[i].len);
12725d12450
< }
12727d12451
<
12729,12734d12452
<
< bailout_error:
<
< ctl_send_datamove_done(io, /*have_lock*/ 0);
<
< return (retval);
12743d12460
< struct ctl_sg_entry *remote_dma_sglist, *local_dma_sglist;
12745,12746c12462
< int retval;
< int i, j;
---
> int i, j, isc_ret;
12748,12749d12463
< retval = 0;
<
12774,12776c12488
< retval = 1;
<
< goto bailout;
---
> return (1);
12780d12491
< local_dma_sglist = io->io_hdr.local_dma_sglist;
12782d12492
< remote_dma_sglist = io->io_hdr.remote_dma_sglist;
12787,12793d12496
< if (io->io_hdr.flags & CTL_FLAG_REDIR_DONE) {
< rq->ret = CTL_HA_STATUS_SUCCESS;
< rq->context = io;
< callback(rq);
< goto bailout;
< }
<
12803a12507
> isc_ret = CTL_HA_STATUS_SUCCESS;
12805,12806c12509
< int isc_ret;
< uint32_t cur_len, dma_length;
---
> uint32_t cur_len;
12809d12511
< rq->id = CTL_HA_DATA_CTL;
12820a12523
> rq->size = cur_len;
12822,12855d12524
< /*
< * In this case, we have a size issue and need to decrease
< * the size, except in the case where we actually have less
< * than 8 bytes left. In that case, we need to increase
< * the DMA length to get the last bit.
< */
< if ((cur_len & 0x7) != 0) {
< if (cur_len > 0x7) {
< cur_len = cur_len - (cur_len & 0x7);
< dma_length = cur_len;
< } else {
< CTL_SIZE_8B(dma_length, cur_len);
< }
<
< } else
< dma_length = cur_len;
<
< /*
< * If we had to allocate memory for this I/O, instead of using
< * the non-cached mirror memory, we'll need to flush the cache
< * before trying to DMA to the other controller.
< *
< * We could end up doing this multiple times for the same
< * segment if we have a larger local segment than remote
< * segment. That shouldn't be an issue.
< */
< if ((io->io_hdr.flags & CTL_FLAG_NO_DATASYNC) == 0) {
< /*
< * XXX KDM use bus_dmamap_sync() here.
< */
< }
<
< rq->size = dma_length;
<
12858a12528
> #if 0
12862d12531
< #if 0
12864d12532
< #endif
12866a12535,12539
> #else
> KASSERT((io->io_hdr.flags & CTL_FLAG_BUS_ADDR) == 0,
> ("HA does not support BUS_ADDR"));
> rq->local = tmp_ptr;
> #endif
12890,12901d12562
< if ((rq->size & 0x7) != 0) {
< printf("%s: warning: size %d is not on 8b boundary\n",
< __func__, rq->size);
< }
< if (((uintptr_t)rq->local & 0x7) != 0) {
< printf("%s: warning: local %p not on 8b boundary\n",
< __func__, rq->local);
< }
< if (((uintptr_t)rq->remote & 0x7) != 0) {
< printf("%s: warning: remote %p not on 8b boundary\n",
< __func__, rq->local);
< }
12909,12916c12570,12574
< if (isc_ret == CTL_HA_STATUS_WAIT)
< continue;
<
< if (isc_ret == CTL_HA_STATUS_DISCONNECT) {
< rq->ret = CTL_HA_STATUS_SUCCESS;
< } else {
< rq->ret = isc_ret;
< }
---
> if (isc_ret > CTL_HA_STATUS_SUCCESS)
> break;
> }
> if (isc_ret != CTL_HA_STATUS_WAIT) {
> rq->ret = isc_ret;
12918d12575
< goto bailout;
12921,12923c12578
< bailout:
< return (retval);
<
---
> return (0);
12942,12943c12597
< if ((retval != 0)
< && ((io->io_hdr.flags & CTL_FLAG_AUTO_MIRROR) == 0)) {
---
> if (retval != 0) {
12951a12606,12608
> free(io->io_hdr.remote_sglist, M_CTL);
> io->io_hdr.remote_sglist = NULL;
> io->io_hdr.local_sglist = NULL;
12967d12623
< struct ctl_softc *softc;
12969c12625
< softc = control_softc;
---
> mtx_assert(&control_softc->ctl_lock, MA_NOTOWNED);
12971c12627,12630
< mtx_assert(&softc->ctl_lock, MA_NOTOWNED);
---
> if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
> ctl_failover_io(io, /*have_lock*/ 0);
> return;
> }
12989c12648
< if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT) {
---
> if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_OUT)
12991c12650
< } else if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN){
---
> else if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN)
12993,13034c12652,12654
< } else {
< union ctl_ha_msg msg;
< struct scsi_sense_data *sense;
< uint8_t sks[3];
< int retry_count;
<
< memset(&msg, 0, sizeof(msg));
<
< msg.hdr.msg_type = CTL_MSG_BAD_JUJU;
< msg.hdr.status = CTL_SCSI_ERROR;
< msg.scsi.scsi_status = SCSI_STATUS_CHECK_COND;
<
< retry_count = 4243;
<
< sense = &msg.scsi.sense_data;
< sks[0] = SSD_SCS_VALID;
< sks[1] = (retry_count >> 8) & 0xff;
< sks[2] = retry_count & 0xff;
<
< /* "Internal target failure" */
< scsi_set_sense_data(sense,
< /*sense_format*/ SSD_TYPE_NONE,
< /*current_error*/ 1,
< /*sense_key*/ SSD_KEY_HARDWARE_ERROR,
< /*asc*/ 0x44,
< /*ascq*/ 0x00,
< /*type*/ SSD_ELEM_SKS,
< /*size*/ sizeof(sks),
< /*data*/ sks,
< SSD_ELEM_NONE);
<
< io->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
< if (io->io_hdr.flags & CTL_FLAG_FAILOVER) {
< ctl_failover_io(io, /*have_lock*/ 1);
< return;
< }
<
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg, sizeof(msg), 0) >
< CTL_HA_STATUS_SUCCESS) {
< /* XXX KDM what to do if this fails? */
< }
< return;
---
> else {
> io->io_hdr.port_status = 31339;
> ctl_send_datamove_done(io, /*have_lock*/ 0);
13036d12655
<
13045c12664,12665
< uint32_t targ_port = ctl_port_idx(io->io_hdr.nexus.targ_port);
---
> union ctl_ha_msg msg;
> uint32_t targ_port = io->io_hdr.nexus.targ_port;
13049c12669,12672
< fe_done = softc->ctl_ports[targ_port]->fe_done;
---
> if ((io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) == 0)
> fe_done = softc->ctl_ports[targ_port]->fe_done;
> else
> fe_done = NULL;
13207,13215d12829
< *
< * We only send status to the other controller if we're in XFER
< * mode. In SER_ONLY mode, the I/O is done on the controller that
< * received the I/O (from CTL's perspective), and so the status is
< * generated there.
< *
< * XXX KDM if we hold the lock here, we could cause a deadlock
< * if the frontend comes back in in this context to queue
< * something.
13216a12831,12840
> if ((softc->ha_mode != CTL_HA_MODE_XFER) &&
> (io->io_hdr.flags & CTL_FLAG_SENT_2OTHER_SC)) {
> memset(&msg, 0, sizeof(msg));
> msg.hdr.msg_type = CTL_MSG_FINISH_IO;
> msg.hdr.serializing_sc = io->io_hdr.serializing_sc;
> msg.hdr.nexus = io->io_hdr.nexus;
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
> sizeof(msg.scsi) - sizeof(msg.scsi.sense_data),
> M_WAITOK);
> }
13219,13220d12842
< union ctl_ha_msg msg;
<
13233c12855
< sizeof(io->scsiio.sense_data));
---
> io->scsiio.sense_len);
13244,13248c12866,12868
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
< sizeof(msg), 0) > CTL_HA_STATUS_SUCCESS) {
< /* XXX do something here */
< }
<
---
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
> sizeof(msg.scsi) - sizeof(msg.scsi.sense_data) +
> msg.scsi.sense_len, M_WAITOK);
13403,13421d13022
< /*
< * We need to send a msg to the serializing shelf to finish the IO
< * as well. We don't send a finish message to the other shelf if
< * this is a task management command. Task management commands
< * aren't serialized in the OOA queue, but rather just executed on
< * both shelf controllers for commands that originated on that
< * controller.
< */
< if ((io->io_hdr.flags & CTL_FLAG_SENT_2OTHER_SC)
< && (io->io_hdr.io_type != CTL_IO_TASK)) {
< union ctl_ha_msg msg_io;
<
< msg_io.hdr.msg_type = CTL_MSG_FINISH_IO;
< msg_io.hdr.serializing_sc = io->io_hdr.serializing_sc;
< if (ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_io,
< sizeof(msg_io), 0 ) != CTL_HA_STATUS_SUCCESS) {
< }
< /* continue on to finish IO */
< }
13452,13469d13052
< int
< ctl_isc(struct ctl_scsiio *ctsio)
< {
< struct ctl_lun *lun;
< int retval;
<
< lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
<
< CTL_DEBUG_PRINT(("ctl_isc: command: %02x\n", ctsio->cdb[0]));
<
< CTL_DEBUG_PRINT(("ctl_isc: calling data_submit()\n"));
<
< retval = lun->backend->data_submit((union ctl_io *)ctsio);
<
< return (retval);
< }
<
<
13519,13528c13102,13109
< if (!ctl_pause_rtr) {
< io = (union ctl_io *)STAILQ_FIRST(&thr->rtr_queue);
< if (io != NULL) {
< STAILQ_REMOVE_HEAD(&thr->rtr_queue, links);
< mtx_unlock(&thr->queue_lock);
< retval = ctl_scsiio(&io->scsiio);
< if (retval != CTL_RETVAL_COMPLETE)
< CTL_DEBUG_PRINT(("ctl_scsiio failed\n"));
< continue;
< }
---
> io = (union ctl_io *)STAILQ_FIRST(&thr->rtr_queue);
> if (io != NULL) {
> STAILQ_REMOVE_HEAD(&thr->rtr_queue, links);
> mtx_unlock(&thr->queue_lock);
> retval = ctl_scsiio(&io->scsiio);
> if (retval != CTL_RETVAL_COMPLETE)
> CTL_DEBUG_PRINT(("ctl_scsiio failed\n"));
> continue;
13570a13152
> union ctl_ha_msg msg;
13572c13154
< int i, e;
---
> int i, e, set;
13583a13166,13168
> if ((lun->flags & CTL_LUN_PRIMARY_SC) == 0 &&
> softc->ha_mode == CTL_HA_MODE_XFER)
> continue;
13628c13213,13215
< }
---
> set = 1;
> } else
> set = 0;
13631a13219
> set = -1;
13633a13222,13238
> if (set != 0 &&
> lun->ctl_softc->ha_mode == CTL_HA_MODE_XFER) {
> /* Send msg to other side. */
> bzero(&msg.ua, sizeof(msg.ua));
> msg.hdr.msg_type = CTL_MSG_UA;
> msg.hdr.nexus.initid = -1;
> msg.hdr.nexus.targ_port = -1;
> msg.hdr.nexus.targ_lun = lun->lun;
> msg.hdr.nexus.targ_mapped_lun = lun->lun;
> msg.ua.ua_all = 1;
> msg.ua.ua_set = (set > 0);
> msg.ua.ua_type = CTL_UA_THIN_PROV_THRES;
> mtx_unlock(&softc->ctl_lock); // XXX
> ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
> sizeof(msg.ua), M_WAITOK);
> mtx_lock(&softc->ctl_lock);
> }
13682d13286
< #ifdef notyet
13696,13703d13299
< /* Initialization and failover */
<
< void
< ctl_init_isc_msg(void)
< {
< printf("CTL: Still calling this thing\n");
< }
<
13705,13797d13300
< * Init component
< * Initializes component into configuration defined by bootMode
< * (see hasc-sv.c)
< * returns hasc_Status:
< * OK
< * ERROR - fatal error
< */
< static ctl_ha_comp_status
< ctl_isc_init(struct ctl_ha_component *c)
< {
< ctl_ha_comp_status ret = CTL_HA_COMP_STATUS_OK;
<
< c->status = ret;
< return ret;
< }
<
< /* Start component
< * Starts component in state requested. If component starts successfully,
< * it must set its own state to the requestrd state
< * When requested state is HASC_STATE_HA, the component may refine it
< * by adding _SLAVE or _MASTER flags.
< * Currently allowed state transitions are:
< * UNKNOWN->HA - initial startup
< * UNKNOWN->SINGLE - initial startup when no parter detected
< * HA->SINGLE - failover
< * returns ctl_ha_comp_status:
< * OK - component successfully started in requested state
< * FAILED - could not start the requested state, failover may
< * be possible
< * ERROR - fatal error detected, no future startup possible
< */
< static ctl_ha_comp_status
< ctl_isc_start(struct ctl_ha_component *c, ctl_ha_state state)
< {
< ctl_ha_comp_status ret = CTL_HA_COMP_STATUS_OK;
<
< printf("%s: go\n", __func__);
<
< // UNKNOWN->HA or UNKNOWN->SINGLE (bootstrap)
< if (c->state == CTL_HA_STATE_UNKNOWN ) {
< control_softc->is_single = 0;
< if (ctl_ha_msg_create(CTL_HA_CHAN_CTL, ctl_isc_event_handler)
< != CTL_HA_STATUS_SUCCESS) {
< printf("ctl_isc_start: ctl_ha_msg_create failed.\n");
< ret = CTL_HA_COMP_STATUS_ERROR;
< }
< } else if (CTL_HA_STATE_IS_HA(c->state)
< && CTL_HA_STATE_IS_SINGLE(state)){
< // HA->SINGLE transition
< ctl_failover();
< control_softc->is_single = 1;
< } else {
< printf("ctl_isc_start:Invalid state transition %X->%X\n",
< c->state, state);
< ret = CTL_HA_COMP_STATUS_ERROR;
< }
< if (CTL_HA_STATE_IS_SINGLE(state))
< control_softc->is_single = 1;
<
< c->state = state;
< c->status = ret;
< return ret;
< }
<
< /*
< * Quiesce component
< * The component must clear any error conditions (set status to OK) and
< * prepare itself to another Start call
< * returns ctl_ha_comp_status:
< * OK
< * ERROR
< */
< static ctl_ha_comp_status
< ctl_isc_quiesce(struct ctl_ha_component *c)
< {
< int ret = CTL_HA_COMP_STATUS_OK;
<
< ctl_pause_rtr = 1;
< c->status = ret;
< return ret;
< }
<
< struct ctl_ha_component ctl_ha_component_ctlisc =
< {
< .name = "CTL ISC",
< .state = CTL_HA_STATE_UNKNOWN,
< .init = ctl_isc_init,
< .start = ctl_isc_start,
< .quiesce = ctl_isc_quiesce
< };
< #endif
<
< /*