Date: Fri, 4 Jul 2014 19:27:07 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268266 - head/sys/cam/ctl Message-ID: <201407041927.s64JR7CG030357@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Fri Jul 4 19:27:06 2014 New Revision: 268266 URL: http://svnweb.freebsd.org/changeset/base/268266 Log: Separate concepts of frontend and port. Before iSCSI implementation CTL had no knowledge about frontend drivers, it had only frontends, which really were ports (alike to LUNs, if comparing to backends). But iSCSI added there ioctl() method, which does not belong to frontend as a port, but belongs to a frontend driver. Modified: head/sys/cam/ctl/ctl.c head/sys/cam/ctl/ctl_frontend.c head/sys/cam/ctl/ctl_frontend.h head/sys/cam/ctl/ctl_frontend_cam_sim.c head/sys/cam/ctl/ctl_frontend_internal.c head/sys/cam/ctl/ctl_frontend_iscsi.c head/sys/cam/ctl/ctl_frontend_iscsi.h head/sys/cam/ctl/ctl_private.h head/sys/cam/ctl/scsi_ctl.c Modified: head/sys/cam/ctl/ctl.c ============================================================================== --- head/sys/cam/ctl/ctl.c Fri Jul 4 19:19:03 2014 (r268265) +++ head/sys/cam/ctl/ctl.c Fri Jul 4 19:27:06 2014 (r268266) @@ -466,6 +466,11 @@ static moduledata_t ctl_moduledata = { DECLARE_MODULE(ctl, ctl_moduledata, SI_SUB_CONFIGURE, SI_ORDER_THIRD); MODULE_VERSION(ctl, 1); +static struct ctl_frontend ioctl_frontend = +{ + .name = "ioctl", +}; + static void ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc, union ctl_ha_msg *msg_info) @@ -926,7 +931,7 @@ ctl_init(void) { struct ctl_softc *softc; struct ctl_io_pool *internal_pool, *emergency_pool, *other_pool; - struct ctl_frontend *fe; + struct ctl_port *port; uint8_t sc_id =0; int i, error, retval; //int isc_retval; @@ -1006,6 +1011,7 @@ ctl_init(void) STAILQ_INIT(&softc->lun_list); STAILQ_INIT(&softc->pending_lun_queue); STAILQ_INIT(&softc->fe_list); + STAILQ_INIT(&softc->port_list); STAILQ_INIT(&softc->be_list); STAILQ_INIT(&softc->io_pools); @@ -1083,23 +1089,25 @@ ctl_init(void) /* * Initialize the ioctl front end. */ - fe = &softc->ioctl_info.fe; - sprintf(softc->ioctl_info.port_name, "CTL ioctl"); - fe->port_type = CTL_PORT_IOCTL; - fe->num_requested_ctl_io = 100; - fe->port_name = softc->ioctl_info.port_name; - fe->port_online = ctl_ioctl_online; - fe->port_offline = ctl_ioctl_offline; - fe->onoff_arg = &softc->ioctl_info; - fe->lun_enable = ctl_ioctl_lun_enable; - fe->lun_disable = ctl_ioctl_lun_disable; - fe->targ_lun_arg = &softc->ioctl_info; - fe->fe_datamove = ctl_ioctl_datamove; - fe->fe_done = ctl_ioctl_done; - fe->max_targets = 15; - fe->max_target_id = 15; + ctl_frontend_register(&ioctl_frontend); + port = &softc->ioctl_info.port; + port->frontend = &ioctl_frontend; + sprintf(softc->ioctl_info.port_name, "ioctl"); + port->port_type = CTL_PORT_IOCTL; + port->num_requested_ctl_io = 100; + port->port_name = softc->ioctl_info.port_name; + port->port_online = ctl_ioctl_online; + port->port_offline = ctl_ioctl_offline; + port->onoff_arg = &softc->ioctl_info; + port->lun_enable = ctl_ioctl_lun_enable; + port->lun_disable = ctl_ioctl_lun_disable; + port->targ_lun_arg = &softc->ioctl_info; + port->fe_datamove = ctl_ioctl_datamove; + port->fe_done = ctl_ioctl_done; + port->max_targets = 15; + port->max_target_id = 15; - if (ctl_frontend_register(&softc->ioctl_info.fe, + if (ctl_port_register(&softc->ioctl_info.port, (softc->flags & CTL_FLAG_MASTER_SHELF)) != 0) { printf("ctl: ioctl front end registration failed, will " "continue anyway\n"); @@ -1125,7 +1133,7 @@ ctl_shutdown(void) softc = (struct ctl_softc *)control_softc; - if (ctl_frontend_deregister(&softc->ioctl_info.fe) != 0) + if (ctl_port_deregister(&softc->ioctl_info.port) != 0) printf("ctl: ioctl front end deregistration failed\n"); mtx_lock(&softc->ctl_lock); @@ -1140,6 +1148,8 @@ ctl_shutdown(void) mtx_unlock(&softc->ctl_lock); + ctl_frontend_deregister(&ioctl_frontend); + /* * This will rip the rug out from under any FETDs or anyone else * that has a pool allocated. Since we increment our module @@ -1204,7 +1214,7 @@ int ctl_port_enable(ctl_port_type port_type) { struct ctl_softc *softc; - struct ctl_frontend *fe; + struct ctl_port *port; if (ctl_is_single == 0) { union ctl_ha_msg msg_info; @@ -1233,13 +1243,13 @@ ctl_port_enable(ctl_port_type port_type) softc = control_softc; - STAILQ_FOREACH(fe, &softc->fe_list, links) { - if (port_type & fe->port_type) + STAILQ_FOREACH(port, &softc->port_list, links) { + if (port_type & port->port_type) { #if 0 - printf("port %d\n", fe->targ_port); + printf("port %d\n", port->targ_port); #endif - ctl_frontend_online(fe); + ctl_port_online(port); } } @@ -1250,13 +1260,13 @@ int ctl_port_disable(ctl_port_type port_type) { struct ctl_softc *softc; - struct ctl_frontend *fe; + struct ctl_port *port; softc = control_softc; - STAILQ_FOREACH(fe, &softc->fe_list, links) { - if (port_type & fe->port_type) - ctl_frontend_offline(fe); + STAILQ_FOREACH(port, &softc->port_list, links) { + if (port_type & port->port_type) + ctl_port_offline(port); } return (0); @@ -1274,7 +1284,7 @@ ctl_port_list(struct ctl_port_entry *ent ctl_port_type port_type, int no_virtual) { struct ctl_softc *softc; - struct ctl_frontend *fe; + struct ctl_port *port; int entries_dropped, entries_filled; int retval; int i; @@ -1287,14 +1297,14 @@ ctl_port_list(struct ctl_port_entry *ent i = 0; mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(fe, &softc->fe_list, links) { + STAILQ_FOREACH(port, &softc->port_list, links) { struct ctl_port_entry *entry; - if ((fe->port_type & port_type) == 0) + if ((port->port_type & port_type) == 0) continue; if ((no_virtual != 0) - && (fe->virtual_port != 0)) + && (port->virtual_port != 0)) continue; if (entries_filled >= num_entries_alloced) { @@ -1303,13 +1313,13 @@ ctl_port_list(struct ctl_port_entry *ent } entry = &entries[i]; - entry->port_type = fe->port_type; - strlcpy(entry->port_name, fe->port_name, + entry->port_type = port->port_type; + strlcpy(entry->port_name, port->port_name, sizeof(entry->port_name)); - entry->physical_port = fe->physical_port; - entry->virtual_port = fe->virtual_port; - entry->wwnn = fe->wwnn; - entry->wwpn = fe->wwpn; + entry->physical_port = port->physical_port; + entry->virtual_port = port->virtual_port; + entry->wwnn = port->wwnn; + entry->wwpn = port->wwpn; i++; entries_filled++; @@ -2134,7 +2144,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, break; } - io = ctl_alloc_io(softc->ioctl_info.fe.ctl_pool_ref); + io = ctl_alloc_io(softc->ioctl_info.port.ctl_pool_ref); if (io == NULL) { printf("ctl_ioctl: can't allocate ctl_io!\n"); retval = ENOSPC; @@ -2158,7 +2168,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, /* * The user sets the initiator ID, target and LUN IDs. */ - io->io_hdr.nexus.targ_port = softc->ioctl_info.fe.targ_port; + io->io_hdr.nexus.targ_port = softc->ioctl_info.port.targ_port; io->io_hdr.flags |= CTL_FLAG_USER_REQ; if ((io->io_hdr.io_type == CTL_IO_SCSI) && (io->scsiio.tag_type != CTL_TAG_UNTAGGED)) @@ -2181,20 +2191,20 @@ ctl_ioctl(struct cdev *dev, u_long cmd, case CTL_ENABLE_PORT: case CTL_DISABLE_PORT: case CTL_SET_PORT_WWNS: { - struct ctl_frontend *fe; + struct ctl_port *port; struct ctl_port_entry *entry; entry = (struct ctl_port_entry *)addr; mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(fe, &softc->fe_list, links) { + STAILQ_FOREACH(port, &softc->port_list, links) { int action, done; action = 0; done = 0; if ((entry->port_type == CTL_PORT_NONE) - && (entry->targ_port == fe->targ_port)) { + && (entry->targ_port == port->targ_port)) { /* * If the user only wants to enable or * disable or set WWNs on a specific port, @@ -2202,7 +2212,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, */ action = 1; done = 1; - } else if (entry->port_type & fe->port_type) { + } else if (entry->port_type & port->port_type) { /* * Compare the user's type mask with the * particular frontend type to see if we @@ -2237,21 +2247,21 @@ ctl_ioctl(struct cdev *dev, u_long cmd, STAILQ_FOREACH(lun, &softc->lun_list, links) { - fe->lun_enable(fe->targ_lun_arg, + port->lun_enable(port->targ_lun_arg, lun->target, lun->lun); } - ctl_frontend_online(fe); + ctl_port_online(port); } else if (cmd == CTL_DISABLE_PORT) { struct ctl_lun *lun; - ctl_frontend_offline(fe); + ctl_port_offline(port); STAILQ_FOREACH(lun, &softc->lun_list, links) { - fe->lun_disable( - fe->targ_lun_arg, + port->lun_disable( + port->targ_lun_arg, lun->target, lun->lun); } @@ -2260,7 +2270,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, mtx_lock(&softc->ctl_lock); if (cmd == CTL_SET_PORT_WWNS) - ctl_frontend_set_wwns(fe, + ctl_port_set_wwns(port, (entry->flags & CTL_PORT_WWNN_VALID) ? 1 : 0, entry->wwnn, (entry->flags & CTL_PORT_WWPN_VALID) ? @@ -2273,7 +2283,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, break; } case CTL_GET_PORT_LIST: { - struct ctl_frontend *fe; + struct ctl_port *port; struct ctl_port_list *list; int i; @@ -2293,7 +2303,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, list->dropped_num = 0; i = 0; mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(fe, &softc->fe_list, links) { + STAILQ_FOREACH(port, &softc->port_list, links) { struct ctl_port_entry entry, *list_entry; if (list->fill_num >= list->alloc_num) { @@ -2301,15 +2311,15 @@ ctl_ioctl(struct cdev *dev, u_long cmd, continue; } - entry.port_type = fe->port_type; - strlcpy(entry.port_name, fe->port_name, + entry.port_type = port->port_type; + strlcpy(entry.port_name, port->port_name, sizeof(entry.port_name)); - entry.targ_port = fe->targ_port; - entry.physical_port = fe->physical_port; - entry.virtual_port = fe->virtual_port; - entry.wwnn = fe->wwnn; - entry.wwpn = fe->wwpn; - if (fe->status & CTL_PORT_STATUS_ONLINE) + entry.targ_port = port->targ_port; + entry.physical_port = port->physical_port; + entry.virtual_port = port->virtual_port; + entry.wwnn = port->wwnn; + entry.wwpn = port->wwpn; + if (port->status & CTL_PORT_STATUS_ONLINE) entry.online = 1; else entry.online = 0; @@ -2844,6 +2854,7 @@ ctl_ioctl(struct cdev *dev, u_long cmd, } case CTL_DUMP_STRUCTS: { int i, j, k; + struct ctl_port *port; struct ctl_frontend *fe; printf("CTL IID to WWPN map start:\n"); @@ -2881,26 +2892,25 @@ ctl_ioctl(struct cdev *dev, u_long cmd, } } printf("CTL Persistent Reservation information end\n"); - printf("CTL Frontends:\n"); + printf("CTL Ports:\n"); /* * XXX KDM calling this without a lock. We'd likely want * to drop the lock before calling the frontend's dump * routine anyway. */ + STAILQ_FOREACH(port, &softc->port_list, links) { + printf("Port %s Frontend %s Type %u pport %d vport %d WWNN " + "%#jx WWPN %#jx\n", port->port_name, + port->frontend->name, port->port_type, + port->physical_port, port->virtual_port, + (uintmax_t)port->wwnn, (uintmax_t)port->wwpn); + } + printf("CTL Port information end\n"); + printf("CTL Frontends:\n"); STAILQ_FOREACH(fe, &softc->fe_list, links) { - printf("Frontend %s Type %u pport %d vport %d WWNN " - "%#jx WWPN %#jx\n", fe->port_name, fe->port_type, - fe->physical_port, fe->virtual_port, - (uintmax_t)fe->wwnn, (uintmax_t)fe->wwpn); - - /* - * Frontends are not required to support the dump - * routine. - */ - if (fe->fe_dump == NULL) - continue; - - fe->fe_dump(); + printf("Frontend %s\n", fe->name); + if (fe->fe_dump != NULL) + fe->fe_dump(); } printf("CTL Frontend information end\n"); break; @@ -3112,14 +3122,15 @@ ctl_ioctl(struct cdev *dev, u_long cmd, mtx_lock(&softc->ctl_lock); STAILQ_FOREACH(fe, &softc->fe_list, links) { - if (strcmp(fe->port_name, "iscsi") == 0) + if (strcmp(fe->name, "iscsi") == 0) break; } mtx_unlock(&softc->ctl_lock); if (fe == NULL) { ci->status = CTL_ISCSI_ERROR; - snprintf(ci->error_str, sizeof(ci->error_str), "Backend \"iscsi\" not found."); + snprintf(ci->error_str, sizeof(ci->error_str), + "Frontend \"iscsi\" not found."); break; } @@ -3378,7 +3389,6 @@ ctl_pool_create(struct ctl_softc *ctl_so #if 0 if ((pool_type != CTL_POOL_EMERGENCY) && (pool_type != CTL_POOL_INTERNAL) - && (pool_type != CTL_POOL_IOCTL) && (pool_type != CTL_POOL_4OTHERSC)) MOD_INC_USE_COUNT; #endif @@ -3432,7 +3442,7 @@ ctl_pool_release(struct ctl_io_pool *poo #if 0 if ((pool->type != CTL_POOL_EMERGENCY) && (pool->type != CTL_POOL_INTERNAL) - && (pool->type != CTL_POOL_IOCTL)) + && (pool->type != CTL_POOL_4OTHERSC)) MOD_DEC_USE_COUNT; #endif @@ -4138,7 +4148,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft struct ctl_be_lun *const be_lun, struct ctl_id target_id) { struct ctl_lun *nlun, *lun; - struct ctl_frontend *fe; + struct ctl_port *port; int lun_number, i, lun_malloced; if (be_lun == NULL) @@ -4287,17 +4297,17 @@ ctl_alloc_lun(struct ctl_softc *ctl_soft * already. Enable the target ID if it hasn't been enabled, and * enable this particular LUN. */ - STAILQ_FOREACH(fe, &ctl_softc->fe_list, links) { + STAILQ_FOREACH(port, &ctl_softc->port_list, links) { int retval; - retval = fe->lun_enable(fe->targ_lun_arg, target_id,lun_number); + retval = port->lun_enable(port->targ_lun_arg, target_id,lun_number); if (retval != 0) { printf("ctl_alloc_lun: FETD %s port %d returned error " "%d for lun_enable on target %ju lun %d\n", - fe->port_name, fe->targ_port, retval, + port->port_name, port->targ_port, retval, (uintmax_t)target_id.id, lun_number); } else - fe->status |= CTL_PORT_STATUS_LUN_ONLINE; + port->status |= CTL_PORT_STATUS_LUN_ONLINE; } return (0); } @@ -4313,7 +4323,7 @@ ctl_free_lun(struct ctl_lun *lun) { struct ctl_softc *softc; #if 0 - struct ctl_frontend *fe; + struct ctl_port *port; #endif struct ctl_lun *nlun; int i; @@ -4337,7 +4347,7 @@ ctl_free_lun(struct ctl_lun *lun) * XXX KDM this scheme only works for a single target/multiple LUN * setup. It needs to be revamped for a multiple target scheme. * - * XXX KDM this results in fe->lun_disable() getting called twice, + * XXX KDM this results in port->lun_disable() getting called twice, * once when ctl_disable_lun() is called, and a second time here. * We really need to re-think the LUN disable semantics. There * should probably be several steps/levels to LUN removal: @@ -4349,37 +4359,37 @@ ctl_free_lun(struct ctl_lun *lun) * the front end ports, at least for individual LUNs. */ #if 0 - STAILQ_FOREACH(fe, &softc->fe_list, links) { + STAILQ_FOREACH(port, &softc->port_list, links) { int retval; - retval = fe->lun_disable(fe->targ_lun_arg, lun->target, + retval = port->lun_disable(port->targ_lun_arg, lun->target, lun->lun); if (retval != 0) { printf("ctl_free_lun: FETD %s port %d returned error " "%d for lun_disable on target %ju lun %jd\n", - fe->port_name, fe->targ_port, retval, + port->port_name, port->targ_port, retval, (uintmax_t)lun->target.id, (intmax_t)lun->lun); } if (STAILQ_FIRST(&softc->lun_list) == NULL) { - fe->status &= ~CTL_PORT_STATUS_LUN_ONLINE; + port->status &= ~CTL_PORT_STATUS_LUN_ONLINE; - retval = fe->targ_disable(fe->targ_lun_arg,lun->target); + retval = port->targ_disable(port->targ_lun_arg,lun->target); if (retval != 0) { printf("ctl_free_lun: FETD %s port %d " "returned error %d for targ_disable on " - "target %ju\n", fe->port_name, - fe->targ_port, retval, + "target %ju\n", port->port_name, + port->targ_port, retval, (uintmax_t)lun->target.id); } else - fe->status &= ~CTL_PORT_STATUS_TARG_ONLINE; + port->status &= ~CTL_PORT_STATUS_TARG_ONLINE; - if ((fe->status & CTL_PORT_STATUS_TARG_ONLINE) != 0) + if ((port->status & CTL_PORT_STATUS_TARG_ONLINE) != 0) continue; #if 0 - fe->port_offline(fe->onoff_arg); - fe->status &= ~CTL_PORT_STATUS_ONLINE; + port->port_offline(port->onoff_arg); + port->status &= ~CTL_PORT_STATUS_ONLINE; #endif } } @@ -4434,7 +4444,7 @@ int ctl_enable_lun(struct ctl_be_lun *be_lun) { struct ctl_softc *ctl_softc; - struct ctl_frontend *fe, *nfe; + struct ctl_port *port, *nport; struct ctl_lun *lun; int retval; @@ -4456,8 +4466,8 @@ ctl_enable_lun(struct ctl_be_lun *be_lun lun->flags &= ~CTL_LUN_DISABLED; mtx_unlock(&lun->lun_lock); - for (fe = STAILQ_FIRST(&ctl_softc->fe_list); fe != NULL; fe = nfe) { - nfe = STAILQ_NEXT(fe, links); + for (port = STAILQ_FIRST(&ctl_softc->port_list); port != NULL; port = nport) { + nport = STAILQ_NEXT(port, links); /* * Drop the lock while we call the FETD's enable routine. @@ -4465,18 +4475,18 @@ ctl_enable_lun(struct ctl_be_lun *be_lun * case of the internal initiator frontend. */ mtx_unlock(&ctl_softc->ctl_lock); - retval = fe->lun_enable(fe->targ_lun_arg, lun->target,lun->lun); + retval = port->lun_enable(port->targ_lun_arg, lun->target,lun->lun); mtx_lock(&ctl_softc->ctl_lock); if (retval != 0) { printf("%s: FETD %s port %d returned error " "%d for lun_enable on target %ju lun %jd\n", - __func__, fe->port_name, fe->targ_port, retval, + __func__, port->port_name, port->targ_port, retval, (uintmax_t)lun->target.id, (intmax_t)lun->lun); } #if 0 else { /* NOTE: TODO: why does lun enable affect port status? */ - fe->status |= CTL_PORT_STATUS_LUN_ONLINE; + port->status |= CTL_PORT_STATUS_LUN_ONLINE; } #endif } @@ -4490,7 +4500,7 @@ int ctl_disable_lun(struct ctl_be_lun *be_lun) { struct ctl_softc *ctl_softc; - struct ctl_frontend *fe; + struct ctl_port *port; struct ctl_lun *lun; int retval; @@ -4508,7 +4518,7 @@ ctl_disable_lun(struct ctl_be_lun *be_lu lun->flags |= CTL_LUN_DISABLED; mtx_unlock(&lun->lun_lock); - STAILQ_FOREACH(fe, &ctl_softc->fe_list, links) { + STAILQ_FOREACH(port, &ctl_softc->port_list, links) { mtx_unlock(&ctl_softc->ctl_lock); /* * Drop the lock before we call the frontend's disable @@ -4517,13 +4527,13 @@ ctl_disable_lun(struct ctl_be_lun *be_lu * XXX KDM what happens if the frontend list changes while * we're traversing it? It's unlikely, but should be handled. */ - retval = fe->lun_disable(fe->targ_lun_arg, lun->target, + retval = port->lun_disable(port->targ_lun_arg, lun->target, lun->lun); mtx_lock(&ctl_softc->ctl_lock); if (retval != 0) { printf("ctl_alloc_lun: FETD %s port %d returned error " "%d for lun_disable on target %ju lun %jd\n", - fe->port_name, fe->targ_port, retval, + port->port_name, port->targ_port, retval, (uintmax_t)lun->target.id, (intmax_t)lun->lun); } } @@ -9475,16 +9485,16 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio struct scsi_vpd_id_t10 *t10id; struct ctl_softc *ctl_softc; struct ctl_lun *lun; - struct ctl_frontend *fe; + struct ctl_port *port; char *val; int data_len, devid_len; ctl_softc = control_softc; - fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; + port = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; - if (fe->devid != NULL) - return ((fe->devid)(ctsio, alloc_len)); + if (port->devid != NULL) + return ((port->devid)(ctsio, alloc_len)); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -9547,7 +9557,7 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio /* * For Fibre channel, */ - if (fe->port_type == CTL_PORT_FC) + if (port->port_type == CTL_PORT_FC) { desc->proto_codeset = (SCSI_PROTO_FC << 4) | SVPD_ID_CODESET_ASCII; @@ -9596,7 +9606,7 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio desc1->identifier[7] += ctsio->io_hdr.nexus.targ_port; #endif - be64enc(desc1->identifier, fe->wwpn); + be64enc(desc1->identifier, port->wwpn); /* * desc2 is for the Relative Target Port(type 4h) identifier Modified: head/sys/cam/ctl/ctl_frontend.c ============================================================================== --- head/sys/cam/ctl/ctl_frontend.c Fri Jul 4 19:19:03 2014 (r268265) +++ head/sys/cam/ctl/ctl_frontend.c Fri Jul 4 19:27:06 2014 (r268266) @@ -66,7 +66,60 @@ __FBSDID("$FreeBSD$"); extern struct ctl_softc *control_softc; int -ctl_frontend_register(struct ctl_frontend *fe, int master_shelf) +ctl_frontend_register(struct ctl_frontend *fe) +{ + struct ctl_frontend *fe_tmp; + + KASSERT(control_softc != NULL, ("CTL is not initialized")); + + /* + * Sanity check, make sure this isn't a duplicate registration. + */ + mtx_lock(&control_softc->ctl_lock); + STAILQ_FOREACH(fe_tmp, &control_softc->fe_list, links) { + if (strcmp(fe_tmp->name, fe->name) == 0) { + mtx_unlock(&control_softc->ctl_lock); + return (-1); + } + } + mtx_unlock(&control_softc->ctl_lock); + STAILQ_INIT(&fe->port_list); + + /* + * Call the frontend's initialization routine. + */ + if (fe->init != NULL) + fe->init(); + + mtx_lock(&control_softc->ctl_lock); + control_softc->num_frontends++; + STAILQ_INSERT_TAIL(&control_softc->fe_list, fe, links); + mtx_unlock(&control_softc->ctl_lock); + return (0); +} + +int +ctl_frontend_deregister(struct ctl_frontend *fe) +{ + + if (!STAILQ_EMPTY(&fe->port_list)) + return (-1); + + mtx_lock(&control_softc->ctl_lock); + STAILQ_REMOVE(&control_softc->fe_list, fe, ctl_frontend, links); + control_softc->num_frontends--; + mtx_unlock(&control_softc->ctl_lock); + + /* + * Call the frontend's shutdown routine. + */ + if (fe->shutdown != NULL) + fe->shutdown(); + return (0); +} + +int +ctl_port_register(struct ctl_port *port, int master_shelf) { struct ctl_io_pool *pool; int port_num; @@ -80,13 +133,13 @@ ctl_frontend_register(struct ctl_fronten port_num = ctl_ffz(&control_softc->ctl_port_mask, CTL_MAX_PORTS); if ((port_num == -1) || (ctl_set_mask(&control_softc->ctl_port_mask, port_num) == -1)) { - fe->targ_port = -1; + port->targ_port = -1; mtx_unlock(&control_softc->ctl_lock); return (1); } - control_softc->num_frontends++; - + control_softc->num_ports++; mtx_unlock(&control_softc->ctl_lock); + /* * We add 20 to whatever the caller requests, so he doesn't get * burned by queueing things back to the pending sense queue. In @@ -95,36 +148,30 @@ ctl_frontend_register(struct ctl_fronten * pending sense queue on the next command, whether or not it is * a REQUEST SENSE. */ - retval = ctl_pool_create(control_softc, - (fe->port_type != CTL_PORT_IOCTL) ? - CTL_POOL_FETD : CTL_POOL_IOCTL, - fe->num_requested_ctl_io + 20, &pool); + retval = ctl_pool_create(control_softc, CTL_POOL_FETD, + port->num_requested_ctl_io + 20, &pool); if (retval != 0) { - fe->targ_port = -1; + port->targ_port = -1; mtx_lock(&control_softc->ctl_lock); ctl_clear_mask(&control_softc->ctl_port_mask, port_num); mtx_unlock(&control_softc->ctl_lock); return (retval); } + port->ctl_pool_ref = pool; mtx_lock(&control_softc->ctl_lock); - - /* For now assume master shelf */ - //fe->targ_port = port_num; - fe->targ_port = port_num + (master_shelf!=0 ? 0 : CTL_MAX_PORTS); - fe->max_initiators = CTL_MAX_INIT_PER_PORT; - STAILQ_INSERT_TAIL(&control_softc->fe_list, fe, links); - control_softc->ctl_ports[port_num] = fe; - + port->targ_port = port_num + (master_shelf != 0 ? 0 : CTL_MAX_PORTS); + port->max_initiators = CTL_MAX_INIT_PER_PORT; + STAILQ_INSERT_TAIL(&port->frontend->port_list, port, links); + STAILQ_INSERT_TAIL(&control_softc->port_list, port, links); + control_softc->ctl_ports[port_num] = port; mtx_unlock(&control_softc->ctl_lock); - fe->ctl_pool_ref = pool; - return (retval); } int -ctl_frontend_deregister(struct ctl_frontend *fe) +ctl_port_deregister(struct ctl_port *port) { struct ctl_io_pool *pool; int port_num; @@ -132,18 +179,19 @@ ctl_frontend_deregister(struct ctl_front retval = 0; - pool = (struct ctl_io_pool *)fe->ctl_pool_ref; + pool = (struct ctl_io_pool *)port->ctl_pool_ref; - if (fe->targ_port == -1) { + if (port->targ_port == -1) { retval = 1; goto bailout; } mtx_lock(&control_softc->ctl_lock); - STAILQ_REMOVE(&control_softc->fe_list, fe, ctl_frontend, links); - control_softc->num_frontends--; - port_num = (fe->targ_port < CTL_MAX_PORTS) ? fe->targ_port : - fe->targ_port - CTL_MAX_PORTS; + STAILQ_REMOVE(&control_softc->port_list, port, ctl_port, links); + STAILQ_REMOVE(&port->frontend->port_list, port, ctl_port, fe_links); + control_softc->num_ports--; + port_num = (port->targ_port < CTL_MAX_PORTS) ? port->targ_port : + port->targ_port - CTL_MAX_PORTS; ctl_clear_mask(&control_softc->ctl_port_mask, port_num); control_softc->ctl_ports[port_num] = NULL; mtx_unlock(&control_softc->ctl_lock); @@ -155,30 +203,30 @@ bailout: } void -ctl_frontend_set_wwns(struct ctl_frontend *fe, int wwnn_valid, uint64_t wwnn, +ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, uint64_t wwnn, int wwpn_valid, uint64_t wwpn) { if (wwnn_valid) - fe->wwnn = wwnn; + port->wwnn = wwnn; if (wwpn_valid) - fe->wwpn = wwpn; + port->wwpn = wwpn; } void -ctl_frontend_online(struct ctl_frontend *fe) +ctl_port_online(struct ctl_port *port) { - fe->port_online(fe->onoff_arg); + port->port_online(port->onoff_arg); /* XXX KDM need a lock here? */ - fe->status |= CTL_PORT_STATUS_ONLINE; + port->status |= CTL_PORT_STATUS_ONLINE; } void -ctl_frontend_offline(struct ctl_frontend *fe) +ctl_port_offline(struct ctl_port *port) { - fe->port_offline(fe->onoff_arg); + port->port_offline(port->onoff_arg); /* XXX KDM need a lock here? */ - fe->status &= ~CTL_PORT_STATUS_ONLINE; + port->status &= ~CTL_PORT_STATUS_ONLINE; } /* Modified: head/sys/cam/ctl/ctl_frontend.h ============================================================================== --- head/sys/cam/ctl/ctl_frontend.h Fri Jul 4 19:19:03 2014 (r268265) +++ head/sys/cam/ctl/ctl_frontend.h Fri Jul 4 19:27:06 2014 (r268266) @@ -39,6 +39,8 @@ #ifndef _CTL_FRONTEND_H_ #define _CTL_FRONTEND_H_ +#define CTL_FE_NAME_LEN 32 + typedef enum { CTL_PORT_STATUS_NONE = 0x00, CTL_PORT_STATUS_ONLINE = 0x01, @@ -46,6 +48,8 @@ typedef enum { CTL_PORT_STATUS_LUN_ONLINE = 0x04 } ctl_port_status; +typedef int (*fe_init_t)(void); +typedef void (*fe_shutdown_t)(void); typedef void (*port_func_t)(void *onoff_arg); typedef int (*targ_func_t)(void *arg, struct ctl_id targ_id); typedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id); @@ -53,6 +57,31 @@ typedef int (*fe_ioctl_t)(struct cdev *d struct thread *td); typedef int (*fe_devid_t)(struct ctl_scsiio *ctsio, int alloc_len); +#define CTL_FRONTEND_DECLARE(name, driver) \ + static int name ## _modevent(module_t mod, int type, void *data) \ + { \ + switch (type) { \ + case MOD_LOAD: \ + ctl_frontend_register( \ + (struct ctl_frontend *)data); \ + break; \ + case MOD_UNLOAD: \ + printf(#name " module unload - not possible for this module type\n"); \ + return EINVAL; \ + default: \ + return EOPNOTSUPP; \ + } \ + return 0; \ + } \ + static moduledata_t name ## _mod = { \ + #name, \ + name ## _modevent, \ + (void *)&driver \ + }; \ + DECLARE_MODULE(name, name ## _mod, SI_SUB_CONFIGURE, SI_ORDER_FOURTH); \ + MODULE_DEPEND(name, ctl, 1, 1, 1); \ + MODULE_DEPEND(name, cam, 1, 1, 1) + /* * The ctl_frontend structure is the registration mechanism between a FETD * (Front End Target Driver) and the CTL layer. Here is a description of @@ -179,7 +208,8 @@ typedef int (*fe_devid_t)(struct ctl_scs * links: Linked list pointers, used by CTL. The FETD * shouldn't touch this field. */ -struct ctl_frontend { +struct ctl_port { + struct ctl_frontend *frontend; ctl_port_type port_type; /* passed to CTL */ int num_requested_ctl_io; /* passed to CTL */ char *port_name; /* passed to CTL */ @@ -190,12 +220,10 @@ struct ctl_frontend { void *onoff_arg; /* passed to CTL */ lun_func_t lun_enable; /* passed to CTL */ lun_func_t lun_disable; /* passed to CTL */ - fe_ioctl_t ioctl; /* passed to CTL */ fe_devid_t devid; /* passed to CTL */ void *targ_lun_arg; /* passed to CTL */ void (*fe_datamove)(union ctl_io *io); /* passed to CTL */ void (*fe_done)(union ctl_io *io); /* passed to CTL */ - void (*fe_dump)(void); /* passed to CTL */ int max_targets; /* passed to CTL */ int max_target_id; /* passed to CTL */ int32_t targ_port; /* passed back to FETD */ @@ -204,6 +232,17 @@ struct ctl_frontend { uint64_t wwnn; /* set by CTL before online */ uint64_t wwpn; /* set by CTL before online */ ctl_port_status status; /* used by CTL */ + STAILQ_ENTRY(ctl_port) fe_links; /* used by CTL */ + STAILQ_ENTRY(ctl_port) links; /* used by CTL */ +}; + +struct ctl_frontend { + char name[CTL_FE_NAME_LEN]; /* passed to CTL */ + fe_init_t init; /* passed to CTL */ + fe_ioctl_t ioctl; /* passed to CTL */ + void (*fe_dump)(void); /* passed to CTL */ + fe_shutdown_t shutdown; /* passed to CTL */ + STAILQ_HEAD(, ctl_port) port_list; /* used by CTL */ STAILQ_ENTRY(ctl_frontend) links; /* used by CTL */ }; @@ -211,7 +250,7 @@ struct ctl_frontend { * This may block until resources are allocated. Called at FETD module load * time. Returns 0 for success, non-zero for failure. */ -int ctl_frontend_register(struct ctl_frontend *fe, int master_SC); +int ctl_frontend_register(struct ctl_frontend *fe); /* * Called at FETD module unload time. @@ -220,20 +259,32 @@ int ctl_frontend_register(struct ctl_fro int ctl_frontend_deregister(struct ctl_frontend *fe); /* + * This may block until resources are allocated. Called at FETD module load + * time. Returns 0 for success, non-zero for failure. + */ +int ctl_port_register(struct ctl_port *fe, int master_SC); + +/* + * Called at FETD module unload time. + * Returns 0 for success, non-zero for failure. + */ +int ctl_port_deregister(struct ctl_port *fe); + +/* * Called to set the WWNN and WWPN for a particular frontend. */ -void ctl_frontend_set_wwns(struct ctl_frontend *fe, int wwnn_valid, +void ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, uint64_t wwnn, int wwpn_valid, uint64_t wwpn); /* * Called to bring a particular frontend online. */ -void ctl_frontend_online(struct ctl_frontend *fe); +void ctl_port_online(struct ctl_port *fe); /* * Called to take a particular frontend offline. */ -void ctl_frontend_offline(struct ctl_frontend *fe); +void ctl_port_offline(struct ctl_port *fe); /* * This routine queues I/O and task management requests from the FETD to the Modified: head/sys/cam/ctl/ctl_frontend_cam_sim.c ============================================================================== --- head/sys/cam/ctl/ctl_frontend_cam_sim.c Fri Jul 4 19:19:03 2014 (r268265) +++ head/sys/cam/ctl/ctl_frontend_cam_sim.c Fri Jul 4 19:27:06 2014 (r268266) @@ -74,13 +74,12 @@ struct cfcs_io { }; struct cfcs_softc { - struct ctl_frontend fe; + struct ctl_port port; char port_name[32]; struct cam_sim *sim; struct cam_devq *devq; struct cam_path *path; struct mtx lock; - char lock_desc[32]; uint64_t wwnn; uint64_t wwpn; uint32_t cur_tag_num; @@ -97,7 +96,6 @@ struct cfcs_softc { CAM_SENSE_PHYS) int cfcs_init(void); -void cfcs_shutdown(void); static void cfcs_poll(struct cam_sim *sim); static void cfcs_online(void *arg); static void cfcs_offline(void *arg); @@ -122,25 +120,19 @@ SYSCTL_NODE(_kern_cam, OID_AUTO, ctl2cam SYSCTL_INT(_kern_cam_ctl2cam, OID_AUTO, max_sense, CTLFLAG_RW, &cfcs_max_sense, 0, "Maximum sense data size"); -static int cfcs_module_event_handler(module_t, int /*modeventtype_t*/, void *); - -static moduledata_t cfcs_moduledata = { - "ctlcfcs", - cfcs_module_event_handler, - NULL +static struct ctl_frontend cfcs_frontend = +{ + .name = "camsim", + .init = cfcs_init, }; - -DECLARE_MODULE(ctlcfcs, cfcs_moduledata, SI_SUB_CONFIGURE, SI_ORDER_FOURTH); -MODULE_VERSION(ctlcfcs, 1); -MODULE_DEPEND(ctlcfi, ctl, 1, 1, 1); -MODULE_DEPEND(ctlcfi, cam, 1, 1, 1); +CTL_FRONTEND_DECLARE(ctlcfcs, cfcs_frontend); int cfcs_init(void) { struct cfcs_softc *softc; struct ccb_setasync csa; - struct ctl_frontend *fe; + struct ctl_port *port; #ifdef NEEDTOPORT char wwnn[8]; #endif @@ -149,32 +141,32 @@ cfcs_init(void) softc = &cfcs_softc; retval = 0; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407041927.s64JR7CG030357>