Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/ctl/ctl.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 409 Lines • ▼ Show 20 Lines | SYSCTL_INT(_kern_cam_ctl, OID_AUTO, lun_map_size, CTLFLAG_RWTUN, | ||||
&ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)"); | &ctl_lun_map_size, 0, "Size of per-port LUN map (max LUN + 1)"); | ||||
#ifdef CTL_TIME_IO | #ifdef CTL_TIME_IO | ||||
static int ctl_time_io_secs = CTL_TIME_IO_DEFAULT_SECS; | static int ctl_time_io_secs = CTL_TIME_IO_DEFAULT_SECS; | ||||
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, time_io_secs, CTLFLAG_RWTUN, | SYSCTL_INT(_kern_cam_ctl, OID_AUTO, time_io_secs, CTLFLAG_RWTUN, | ||||
&ctl_time_io_secs, 0, "Log requests taking more seconds"); | &ctl_time_io_secs, 0, "Log requests taking more seconds"); | ||||
#endif | #endif | ||||
/* | /* | ||||
* Maximum number of LUNs we support. MUST be a power of 2. | |||||
*/ | |||||
#define CTL_DEFAULT_MAX_LUNS 1024 | |||||
static int ctl_max_luns = CTL_DEFAULT_MAX_LUNS; | |||||
TUNABLE_INT("kern.cam.ctl.max_luns", &ctl_max_luns); | |||||
trasz: Could you add read-only (CTL_RDTUN) sysctl-s for these two, to make it possible to easily check… | |||||
Done Inline ActionsYeah sure I'll do that. manu: Yeah sure I'll do that. | |||||
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, max_luns, CTLFLAG_RDTUN, | |||||
&ctl_max_luns, CTL_DEFAULT_MAX_LUNS, "Maximum number of LUNs"); | |||||
/* | |||||
* Maximum number of ports registered at one time. | |||||
*/ | |||||
#define CTL_DEFAULT_MAX_PORTS 256 | |||||
static int ctl_max_ports = CTL_DEFAULT_MAX_PORTS; | |||||
TUNABLE_INT("kern.cam.ctl.max_ports", &ctl_max_ports); | |||||
SYSCTL_INT(_kern_cam_ctl, OID_AUTO, max_ports, CTLFLAG_RDTUN, | |||||
&ctl_max_ports, CTL_DEFAULT_MAX_LUNS, "Maximum number of ports"); | |||||
/* | |||||
* Maximum number of initiators we support. | |||||
*/ | |||||
#define CTL_MAX_INITIATORS (CTL_MAX_INIT_PER_PORT * ctl_max_ports) | |||||
/* | |||||
* Supported pages (0x00), Serial number (0x80), Device ID (0x83), | * Supported pages (0x00), Serial number (0x80), Device ID (0x83), | ||||
* Extended INQUIRY Data (0x86), Mode Page Policy (0x87), | * Extended INQUIRY Data (0x86), Mode Page Policy (0x87), | ||||
* SCSI Ports (0x88), Third-party Copy (0x8F), Block limits (0xB0), | * SCSI Ports (0x88), Third-party Copy (0x8F), Block limits (0xB0), | ||||
* Block Device Characteristics (0xB1) and Logical Block Provisioning (0xB2) | * Block Device Characteristics (0xB1) and Logical Block Provisioning (0xB2) | ||||
*/ | */ | ||||
#define SCSI_EVPD_NUM_SUPPORTED_PAGES 10 | #define SCSI_EVPD_NUM_SUPPORTED_PAGES 10 | ||||
static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, | static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, | ||||
▲ Show 20 Lines • Show All 574 Lines • ▼ Show 20 Lines | ctl_isc_ha_link_up(struct ctl_softc *softc) | ||||
union ctl_ha_msg msg; | union ctl_ha_msg msg; | ||||
int i; | int i; | ||||
/* Announce this node parameters to peer for validation. */ | /* Announce this node parameters to peer for validation. */ | ||||
msg.login.msg_type = CTL_MSG_LOGIN; | msg.login.msg_type = CTL_MSG_LOGIN; | ||||
msg.login.version = CTL_HA_VERSION; | msg.login.version = CTL_HA_VERSION; | ||||
msg.login.ha_mode = softc->ha_mode; | msg.login.ha_mode = softc->ha_mode; | ||||
msg.login.ha_id = softc->ha_id; | msg.login.ha_id = softc->ha_id; | ||||
msg.login.max_luns = CTL_MAX_LUNS; | msg.login.max_luns = ctl_max_luns; | ||||
msg.login.max_ports = CTL_MAX_PORTS; | msg.login.max_ports = ctl_max_ports; | ||||
msg.login.max_init_per_port = CTL_MAX_INIT_PER_PORT; | msg.login.max_init_per_port = CTL_MAX_INIT_PER_PORT; | ||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg.login, sizeof(msg.login), | ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg.login, sizeof(msg.login), | ||||
M_WAITOK); | M_WAITOK); | ||||
STAILQ_FOREACH(port, &softc->port_list, links) { | STAILQ_FOREACH(port, &softc->port_list, links) { | ||||
ctl_isc_announce_port(port); | ctl_isc_announce_port(port); | ||||
for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) { | for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) { | ||||
if (port->wwpn_iid[i].in_use) | if (port->wwpn_iid[i].in_use) | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) | ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) | ||||
{ | { | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
uint32_t iid = ctl_get_initindex(&msg->hdr.nexus); | uint32_t iid = ctl_get_initindex(&msg->hdr.nexus); | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (msg->hdr.nexus.targ_mapped_lun >= CTL_MAX_LUNS || | if (msg->hdr.nexus.targ_mapped_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) == NULL) { | (lun = softc->ctl_luns[msg->hdr.nexus.targ_mapped_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
return; | return; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set) | if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set) | ||||
memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8); | memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8); | ||||
Show All 17 Lines | ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
struct ctl_ha_msg_lun_pr_key pr_key; | struct ctl_ha_msg_lun_pr_key pr_key; | ||||
int i, k; | int i, k; | ||||
ctl_lun_flags oflags; | ctl_lun_flags oflags; | ||||
uint32_t targ_lun; | uint32_t targ_lun; | ||||
targ_lun = msg->hdr.nexus.targ_mapped_lun; | targ_lun = msg->hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
return; | return; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
if (lun->flags & CTL_LUN_DISABLED) { | if (lun->flags & CTL_LUN_DISABLED) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 205 Lines • ▼ Show 20 Lines | if (msg->login.ha_mode != softc->ha_mode) { | ||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ||||
return; | return; | ||||
} | } | ||||
if (msg->login.ha_id == softc->ha_id) { | if (msg->login.ha_id == softc->ha_id) { | ||||
printf("CTL HA peers have same ha_id %d\n", msg->login.ha_id); | printf("CTL HA peers have same ha_id %d\n", msg->login.ha_id); | ||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ||||
return; | return; | ||||
} | } | ||||
if (msg->login.max_luns != CTL_MAX_LUNS || | if (msg->login.max_luns != ctl_max_luns || | ||||
msg->login.max_ports != CTL_MAX_PORTS || | msg->login.max_ports != ctl_max_ports || | ||||
msg->login.max_init_per_port != CTL_MAX_INIT_PER_PORT) { | msg->login.max_init_per_port != CTL_MAX_INIT_PER_PORT) { | ||||
printf("CTL HA peers have different limits\n"); | printf("CTL HA peers have different limits\n"); | ||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ctl_ha_msg_abort(CTL_HA_CHAN_CTL); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) | ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len) | ||||
{ | { | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
u_int i; | u_int i; | ||||
uint32_t initidx, targ_lun; | uint32_t initidx, targ_lun; | ||||
targ_lun = msg->hdr.nexus.targ_mapped_lun; | targ_lun = msg->hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
return; | return; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
if (lun->flags & CTL_LUN_DISABLED) { | if (lun->flags & CTL_LUN_DISABLED) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 513 Lines • ▼ Show 20 Lines | ctl_init(void) | ||||
softc->io_zone = uma_zcreate("CTL IO", sizeof(union ctl_io), | softc->io_zone = uma_zcreate("CTL IO", sizeof(union ctl_io), | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | ||||
softc->flags = 0; | softc->flags = 0; | ||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | ||||
OID_AUTO, "ha_mode", CTLFLAG_RDTUN, (int *)&softc->ha_mode, 0, | OID_AUTO, "ha_mode", CTLFLAG_RDTUN, (int *)&softc->ha_mode, 0, | ||||
"HA mode (0 - act/stby, 1 - serialize only, 2 - xfer)"); | "HA mode (0 - act/stby, 1 - serialize only, 2 - xfer)"); | ||||
if (ctl_max_luns <= 0 || powerof2(ctl_max_luns) == 0) { | |||||
printf("Bad value %d for kern.cam.ctl.max_luns, must be a power of two, using %d\n", | |||||
Done Inline ActionsCould you reword it to indicate what the valid value would be? trasz: Could you reword it to indicate what the valid value would be?
| |||||
Done Inline ActionsWill do. manu: Will do. | |||||
ctl_max_luns, CTL_DEFAULT_MAX_LUNS); | |||||
ctl_max_luns = CTL_DEFAULT_MAX_LUNS; | |||||
} | |||||
softc->ctl_luns = malloc(sizeof(struct ctl_lun *) * ctl_max_luns, | |||||
M_DEVBUF, M_WAITOK | M_ZERO); | |||||
softc->ctl_lun_mask = malloc(sizeof(uint32_t) * | |||||
((ctl_max_luns + 31) / 32), M_DEVBUF, M_WAITOK | M_ZERO); | |||||
if (ctl_max_ports <= 0 || powerof2(ctl_max_ports) == 0) { | |||||
printf("Bad value %d for kern.cam.ctl.max_ports, must be a power of two, using %d\n", | |||||
ctl_max_ports, CTL_DEFAULT_MAX_PORTS); | |||||
ctl_max_ports = CTL_DEFAULT_MAX_PORTS; | |||||
} | |||||
softc->ctl_port_mask = malloc(sizeof(uint32_t) * | |||||
((ctl_max_ports + 31) / 32), M_DEVBUF, M_WAITOK | M_ZERO); | |||||
softc->ctl_ports = malloc(sizeof(struct ctl_port *) * ctl_max_ports, | |||||
M_DEVBUF, M_WAITOK | M_ZERO); | |||||
/* | /* | ||||
* In Copan's HA scheme, the "master" and "slave" roles are | * In Copan's HA scheme, the "master" and "slave" roles are | ||||
* figured out through the slot the controller is in. Although it | * figured out through the slot the controller is in. Although it | ||||
* is an active/active system, someone has to be in charge. | * is an active/active system, someone has to be in charge. | ||||
*/ | */ | ||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | ||||
OID_AUTO, "ha_id", CTLFLAG_RDTUN, &softc->ha_id, 0, | OID_AUTO, "ha_id", CTLFLAG_RDTUN, &softc->ha_id, 0, | ||||
"HA head ID (0 - no HA)"); | "HA head ID (0 - no HA)"); | ||||
if (softc->ha_id == 0 || softc->ha_id > NUM_HA_SHELVES) { | if (softc->ha_id == 0 || softc->ha_id > NUM_HA_SHELVES) { | ||||
softc->flags |= CTL_FLAG_ACTIVE_SHELF; | softc->flags |= CTL_FLAG_ACTIVE_SHELF; | ||||
softc->is_single = 1; | softc->is_single = 1; | ||||
softc->port_cnt = CTL_MAX_PORTS; | softc->port_cnt = ctl_max_ports; | ||||
softc->port_min = 0; | softc->port_min = 0; | ||||
} else { | } else { | ||||
softc->port_cnt = CTL_MAX_PORTS / NUM_HA_SHELVES; | softc->port_cnt = ctl_max_ports / NUM_HA_SHELVES; | ||||
softc->port_min = (softc->ha_id - 1) * softc->port_cnt; | softc->port_min = (softc->ha_id - 1) * softc->port_cnt; | ||||
} | } | ||||
softc->port_max = softc->port_min + 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_min = softc->port_min * CTL_MAX_INIT_PER_PORT; | ||||
softc->init_max = softc->port_max * CTL_MAX_INIT_PER_PORT; | softc->init_max = softc->port_max * CTL_MAX_INIT_PER_PORT; | ||||
SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), | ||||
OID_AUTO, "ha_link", CTLFLAG_RD, (int *)&softc->ha_link, 0, | OID_AUTO, "ha_link", CTLFLAG_RD, (int *)&softc->ha_link, 0, | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | while (softc->thresh_thread != NULL) { | ||||
if (softc->thresh_thread != NULL) | if (softc->thresh_thread != NULL) | ||||
pause("CTL thr shutdown", 1); | pause("CTL thr shutdown", 1); | ||||
} | } | ||||
ctl_tpc_shutdown(softc); | ctl_tpc_shutdown(softc); | ||||
uma_zdestroy(softc->io_zone); | uma_zdestroy(softc->io_zone); | ||||
mtx_destroy(&softc->ctl_lock); | mtx_destroy(&softc->ctl_lock); | ||||
free(softc->ctl_luns, M_DEVBUF); | |||||
free(softc->ctl_lun_mask, M_DEVBUF); | |||||
free(softc->ctl_port_mask, M_DEVBUF); | |||||
free(softc->ctl_ports, M_DEVBUF); | |||||
sysctl_ctx_free(&softc->sysctl_ctx); | sysctl_ctx_free(&softc->sysctl_ctx); | ||||
free(softc, M_DEVBUF); | free(softc, M_DEVBUF); | ||||
control_softc = NULL; | control_softc = NULL; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) | ||||
if (port == NULL || (port->status & CTL_PORT_STATUS_ONLINE) == 0) { | if (port == NULL || (port->status & CTL_PORT_STATUS_ONLINE) == 0) { | ||||
ctl_set_internal_failure(ctsio, /*sks_valid*/ 0, | ctl_set_internal_failure(ctsio, /*sks_valid*/ 0, | ||||
/*retry_count*/ 1); | /*retry_count*/ 1); | ||||
goto badjuju; | goto badjuju; | ||||
} | } | ||||
/* Make sure that we know about this LUN. */ | /* Make sure that we know about this LUN. */ | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
/* | /* | ||||
* The other node would not send this request to us unless | * The other node would not send this request to us unless | ||||
* received announce that we are primary node for this LUN. | * received announce that we are primary node for this LUN. | ||||
* If this LUN does not exist now, it is probably result of | * If this LUN does not exist now, it is probably result of | ||||
* a race, so respond to initiator in the most opaque way. | * a race, so respond to initiator in the most opaque way. | ||||
▲ Show 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | if (entries == NULL) { | ||||
printf("%s: could not allocate %d bytes for OOA " | printf("%s: could not allocate %d bytes for OOA " | ||||
"dump\n", __func__, ooa_hdr->alloc_len); | "dump\n", __func__, ooa_hdr->alloc_len); | ||||
retval = ENOMEM; | retval = ENOMEM; | ||||
break; | break; | ||||
} | } | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 && | if ((ooa_hdr->flags & CTL_OOA_FLAG_ALL_LUNS) == 0 && | ||||
(ooa_hdr->lun_num >= CTL_MAX_LUNS || | (ooa_hdr->lun_num >= ctl_max_luns || | ||||
softc->ctl_luns[ooa_hdr->lun_num] == NULL)) { | softc->ctl_luns[ooa_hdr->lun_num] == NULL)) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
free(entries, M_CTL); | free(entries, M_CTL); | ||||
printf("%s: CTL_GET_OOA: invalid LUN %ju\n", | printf("%s: CTL_GET_OOA: invalid LUN %ju\n", | ||||
__func__, (uintmax_t)ooa_hdr->lun_num); | __func__, (uintmax_t)ooa_hdr->lun_num); | ||||
retval = EINVAL; | retval = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
Show All 36 Lines | ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, | ||||
} | } | ||||
case CTL_DELAY_IO: { | case CTL_DELAY_IO: { | ||||
struct ctl_io_delay_info *delay_info; | struct ctl_io_delay_info *delay_info; | ||||
delay_info = (struct ctl_io_delay_info *)addr; | delay_info = (struct ctl_io_delay_info *)addr; | ||||
#ifdef CTL_IO_DELAY | #ifdef CTL_IO_DELAY | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (delay_info->lun_id >= CTL_MAX_LUNS || | if (delay_info->lun_id >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[delay_info->lun_id]) == NULL) { | (lun = softc->ctl_luns[delay_info->lun_id]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
delay_info->status = CTL_DELAY_STATUS_INVALID_LUN; | delay_info->status = CTL_DELAY_STATUS_INVALID_LUN; | ||||
break; | break; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
delay_info->status = CTL_DELAY_STATUS_OK; | delay_info->status = CTL_DELAY_STATUS_OK; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | case CTL_ERROR_INJECT: { | ||||
err_desc = (struct ctl_error_desc *)addr; | err_desc = (struct ctl_error_desc *)addr; | ||||
new_err_desc = malloc(sizeof(*new_err_desc), M_CTL, | new_err_desc = malloc(sizeof(*new_err_desc), M_CTL, | ||||
M_WAITOK | M_ZERO); | M_WAITOK | M_ZERO); | ||||
bcopy(err_desc, new_err_desc, sizeof(*new_err_desc)); | bcopy(err_desc, new_err_desc, sizeof(*new_err_desc)); | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (err_desc->lun_id >= CTL_MAX_LUNS || | if (err_desc->lun_id >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[err_desc->lun_id]) == NULL) { | (lun = softc->ctl_luns[err_desc->lun_id]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
free(new_err_desc, M_CTL); | free(new_err_desc, M_CTL); | ||||
printf("%s: CTL_ERROR_INJECT: invalid LUN %ju\n", | printf("%s: CTL_ERROR_INJECT: invalid LUN %ju\n", | ||||
__func__, (uintmax_t)err_desc->lun_id); | __func__, (uintmax_t)err_desc->lun_id); | ||||
retval = EINVAL; | retval = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
Show All 27 Lines | #endif /* CTL_LEGACY_STATS */ | ||||
case CTL_ERROR_INJECT_DELETE: { | case CTL_ERROR_INJECT_DELETE: { | ||||
struct ctl_error_desc *delete_desc, *desc, *desc2; | struct ctl_error_desc *delete_desc, *desc, *desc2; | ||||
int delete_done; | int delete_done; | ||||
delete_desc = (struct ctl_error_desc *)addr; | delete_desc = (struct ctl_error_desc *)addr; | ||||
delete_done = 0; | delete_done = 0; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (delete_desc->lun_id >= CTL_MAX_LUNS || | if (delete_desc->lun_id >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[delete_desc->lun_id]) == NULL) { | (lun = softc->ctl_luns[delete_desc->lun_id]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
printf("%s: CTL_ERROR_INJECT_DELETE: invalid LUN %ju\n", | printf("%s: CTL_ERROR_INJECT_DELETE: invalid LUN %ju\n", | ||||
__func__, (uintmax_t)delete_desc->lun_id); | __func__, (uintmax_t)delete_desc->lun_id); | ||||
retval = EINVAL; | retval = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
Show All 26 Lines | case CTL_DUMP_STRUCTS: { | ||||
printf("CTL Persistent Reservation information start:\n"); | printf("CTL Persistent Reservation information start:\n"); | ||||
STAILQ_FOREACH(lun, &softc->lun_list, links) { | STAILQ_FOREACH(lun, &softc->lun_list, links) { | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
if ((lun->flags & CTL_LUN_DISABLED) != 0) { | if ((lun->flags & CTL_LUN_DISABLED) != 0) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
continue; | continue; | ||||
} | } | ||||
for (j = 0; j < CTL_MAX_PORTS; j++) { | for (j = 0; j < ctl_max_ports; j++) { | ||||
if (lun->pr_keys[j] == NULL) | if (lun->pr_keys[j] == NULL) | ||||
continue; | continue; | ||||
for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ | for (k = 0; k < CTL_MAX_INIT_PER_PORT; k++){ | ||||
if (lun->pr_keys[j][k] == 0) | if (lun->pr_keys[j][k] == 0) | ||||
continue; | continue; | ||||
printf(" LUN %ju port %d iid %d key " | printf(" LUN %ju port %d iid %d key " | ||||
"%#jx\n", lun->lun, j, k, | "%#jx\n", lun->lun, j, k, | ||||
(uintmax_t)lun->pr_keys[j][k]); | (uintmax_t)lun->pr_keys[j][k]); | ||||
▲ Show 20 Lines • Show All 458 Lines • ▼ Show 20 Lines | if (port->status & CTL_PORT_STATUS_ONLINE) { | ||||
CTL_UA_LUN_CHANGE); | CTL_UA_LUN_CHANGE); | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
} | } | ||||
} | } | ||||
mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps | mtx_unlock(&softc->ctl_lock); // XXX: port_enable sleeps | ||||
if (lm->plun != UINT32_MAX) { | if (lm->plun != UINT32_MAX) { | ||||
if (lm->lun == UINT32_MAX) | if (lm->lun == UINT32_MAX) | ||||
retval = ctl_lun_map_unset(port, lm->plun); | retval = ctl_lun_map_unset(port, lm->plun); | ||||
else if (lm->lun < CTL_MAX_LUNS && | else if (lm->lun < ctl_max_luns && | ||||
softc->ctl_luns[lm->lun] != NULL) | softc->ctl_luns[lm->lun] != NULL) | ||||
retval = ctl_lun_map_set(port, lm->plun, lm->lun); | retval = ctl_lun_map_set(port, lm->plun, lm->lun); | ||||
else | else | ||||
return (ENXIO); | return (ENXIO); | ||||
} else { | } else { | ||||
if (lm->lun == UINT32_MAX) | if (lm->lun == UINT32_MAX) | ||||
retval = ctl_lun_map_deinit(port); | retval = ctl_lun_map_deinit(port); | ||||
else | else | ||||
▲ Show 20 Lines • Show All 1,091 Lines • ▼ Show 20 Lines | if (ctl_lun == NULL) { | ||||
lun_malloced = 0; | lun_malloced = 0; | ||||
lun = ctl_lun; | lun = ctl_lun; | ||||
} | } | ||||
memset(lun, 0, sizeof(*lun)); | memset(lun, 0, sizeof(*lun)); | ||||
if (lun_malloced) | if (lun_malloced) | ||||
lun->flags = CTL_LUN_MALLOCED; | lun->flags = CTL_LUN_MALLOCED; | ||||
lun->pending_sense = malloc(sizeof(struct scsi_sense_data *) * | |||||
ctl_max_ports, M_DEVBUF, M_WAITOK | M_ZERO); | |||||
lun->pending_ua = malloc(sizeof(ctl_ua_type *) * ctl_max_ports, | |||||
M_DEVBUF, M_WAITOK | M_ZERO); | |||||
lun->pr_keys = malloc(sizeof(uint64_t *) * ctl_max_ports, | |||||
M_DEVBUF, M_WAITOK | M_ZERO); | |||||
/* Generate LUN ID. */ | /* Generate LUN ID. */ | ||||
devidlen = max(CTL_DEVID_MIN_LEN, | devidlen = max(CTL_DEVID_MIN_LEN, | ||||
strnlen(be_lun->device_id, CTL_DEVID_LEN)); | strnlen(be_lun->device_id, CTL_DEVID_LEN)); | ||||
idlen1 = sizeof(*t10id) + devidlen; | idlen1 = sizeof(*t10id) + devidlen; | ||||
len = sizeof(struct scsi_vpd_id_descriptor) + idlen1; | len = sizeof(struct scsi_vpd_id_descriptor) + idlen1; | ||||
scsiname = ctl_get_opt(&be_lun->options, "scsiname"); | scsiname = ctl_get_opt(&be_lun->options, "scsiname"); | ||||
if (scsiname != NULL) { | if (scsiname != NULL) { | ||||
idlen2 = roundup2(strlen(scsiname) + 1, 4); | idlen2 = roundup2(strlen(scsiname) + 1, 4); | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun, | ||||
lun->lun_devid->len = len; | lun->lun_devid->len = len; | ||||
mtx_lock(&ctl_softc->ctl_lock); | mtx_lock(&ctl_softc->ctl_lock); | ||||
/* | /* | ||||
* See if the caller requested a particular LUN number. If so, see | * See if the caller requested a particular LUN number. If so, see | ||||
* if it is available. Otherwise, allocate the first available LUN. | * if it is available. Otherwise, allocate the first available LUN. | ||||
*/ | */ | ||||
if (be_lun->flags & CTL_LUN_FLAG_ID_REQ) { | if (be_lun->flags & CTL_LUN_FLAG_ID_REQ) { | ||||
if ((be_lun->req_lun_id > (CTL_MAX_LUNS - 1)) | if ((be_lun->req_lun_id > (ctl_max_luns - 1)) | ||||
|| (ctl_is_set(ctl_softc->ctl_lun_mask, be_lun->req_lun_id))) { | || (ctl_is_set(ctl_softc->ctl_lun_mask, be_lun->req_lun_id))) { | ||||
mtx_unlock(&ctl_softc->ctl_lock); | mtx_unlock(&ctl_softc->ctl_lock); | ||||
if (be_lun->req_lun_id > (CTL_MAX_LUNS - 1)) { | if (be_lun->req_lun_id > (ctl_max_luns - 1)) { | ||||
printf("ctl: requested LUN ID %d is higher " | printf("ctl: requested LUN ID %d is higher " | ||||
"than CTL_MAX_LUNS - 1 (%d)\n", | "than ctl_max_luns - 1 (%d)\n", | ||||
be_lun->req_lun_id, CTL_MAX_LUNS - 1); | be_lun->req_lun_id, ctl_max_luns - 1); | ||||
} else { | } else { | ||||
/* | /* | ||||
* XXX KDM return an error, or just assign | * XXX KDM return an error, or just assign | ||||
* another LUN ID in this case?? | * another LUN ID in this case?? | ||||
*/ | */ | ||||
printf("ctl: requested LUN ID %d is already " | printf("ctl: requested LUN ID %d is already " | ||||
"in use\n", be_lun->req_lun_id); | "in use\n", be_lun->req_lun_id); | ||||
} | } | ||||
fail: | fail: | ||||
free(lun->lun_devid, M_CTL); | free(lun->lun_devid, M_CTL); | ||||
if (lun->flags & CTL_LUN_MALLOCED) | if (lun->flags & CTL_LUN_MALLOCED) | ||||
free(lun, M_CTL); | free(lun, M_CTL); | ||||
be_lun->lun_config_status(be_lun->be_lun, | be_lun->lun_config_status(be_lun->be_lun, | ||||
CTL_LUN_CONFIG_FAILURE); | CTL_LUN_CONFIG_FAILURE); | ||||
return (ENOSPC); | return (ENOSPC); | ||||
} | } | ||||
lun_number = be_lun->req_lun_id; | lun_number = be_lun->req_lun_id; | ||||
} else { | } else { | ||||
lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, 0, CTL_MAX_LUNS); | lun_number = ctl_ffz(ctl_softc->ctl_lun_mask, 0, ctl_max_luns); | ||||
if (lun_number == -1) { | if (lun_number == -1) { | ||||
mtx_unlock(&ctl_softc->ctl_lock); | mtx_unlock(&ctl_softc->ctl_lock); | ||||
printf("ctl: can't allocate LUN, out of LUNs\n"); | printf("ctl: can't allocate LUN, out of LUNs\n"); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
} | } | ||||
ctl_set_mask(ctl_softc->ctl_lun_mask, lun_number); | ctl_set_mask(ctl_softc->ctl_lun_mask, lun_number); | ||||
mtx_unlock(&ctl_softc->ctl_lock); | mtx_unlock(&ctl_softc->ctl_lock); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | #endif | ||||
/* Setup statistics gathering */ | /* Setup statistics gathering */ | ||||
#ifdef CTL_LEGACY_STATS | #ifdef CTL_LEGACY_STATS | ||||
lun->legacy_stats.device_type = be_lun->lun_type; | lun->legacy_stats.device_type = be_lun->lun_type; | ||||
lun->legacy_stats.lun_number = lun_number; | lun->legacy_stats.lun_number = lun_number; | ||||
lun->legacy_stats.blocksize = be_lun->blocksize; | lun->legacy_stats.blocksize = be_lun->blocksize; | ||||
if (be_lun->blocksize == 0) | if (be_lun->blocksize == 0) | ||||
lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE; | lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE; | ||||
for (len = 0; len < CTL_MAX_PORTS; len++) | lun->legacy_stats.ports = malloc(sizeof(struct ctl_lun_io_port_stats) * | ||||
ctl_max_ports, M_DEVBUF, M_WAITOK, M_ZERO); | |||||
for (len = 0; len < ctl_max_ports; len++) | |||||
lun->legacy_stats.ports[len].targ_port = len; | lun->legacy_stats.ports[len].targ_port = len; | ||||
#endif /* CTL_LEGACY_STATS */ | #endif /* CTL_LEGACY_STATS */ | ||||
lun->stats.item = lun_number; | lun->stats.item = lun_number; | ||||
/* | /* | ||||
* Now, before we insert this lun on the lun list, set the lun | * Now, before we insert this lun on the lun list, set the lun | ||||
* inventory changed UA for all other luns. | * inventory changed UA for all other luns. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | ctl_free_lun(struct ctl_lun *lun) | ||||
atomic_subtract_int(&lun->be_lun->be->num_luns, 1); | atomic_subtract_int(&lun->be_lun->be->num_luns, 1); | ||||
lun->be_lun->lun_shutdown(lun->be_lun->be_lun); | lun->be_lun->lun_shutdown(lun->be_lun->be_lun); | ||||
lun->ie_reportcnt = UINT32_MAX; | lun->ie_reportcnt = UINT32_MAX; | ||||
callout_drain(&lun->ie_callout); | callout_drain(&lun->ie_callout); | ||||
ctl_tpc_lun_shutdown(lun); | ctl_tpc_lun_shutdown(lun); | ||||
mtx_destroy(&lun->lun_lock); | mtx_destroy(&lun->lun_lock); | ||||
free(lun->lun_devid, M_CTL); | free(lun->lun_devid, M_CTL); | ||||
for (i = 0; i < CTL_MAX_PORTS; i++) | for (i = 0; i < ctl_max_ports; i++) | ||||
free(lun->pending_ua[i], M_CTL); | free(lun->pending_ua[i], M_CTL); | ||||
for (i = 0; i < CTL_MAX_PORTS; i++) | free(lun->pending_ua, M_DEVBUF); | ||||
for (i = 0; i < ctl_max_ports; i++) | |||||
free(lun->pr_keys[i], M_CTL); | free(lun->pr_keys[i], M_CTL); | ||||
free(lun->pr_keys, M_DEVBUF); | |||||
free(lun->write_buffer, M_CTL); | free(lun->write_buffer, M_CTL); | ||||
free(lun->prevent, M_CTL); | free(lun->prevent, M_CTL); | ||||
if (lun->flags & CTL_LUN_MALLOCED) | if (lun->flags & CTL_LUN_MALLOCED) | ||||
free(lun, M_CTL); | free(lun, M_CTL); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 3,703 Lines • ▼ Show 20 Lines | ctl_hndl_per_res_out_on_other_sc(union ctl_io *io) | ||||
struct ctl_softc *softc = CTL_SOFTC(io); | struct ctl_softc *softc = CTL_SOFTC(io); | ||||
union ctl_ha_msg *msg = (union ctl_ha_msg *)&io->presio.pr_msg; | union ctl_ha_msg *msg = (union ctl_ha_msg *)&io->presio.pr_msg; | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
int i; | int i; | ||||
uint32_t residx, targ_lun; | uint32_t residx, targ_lun; | ||||
targ_lun = msg->hdr.nexus.targ_mapped_lun; | targ_lun = msg->hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
return; | return; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
if (lun->flags & CTL_LUN_DISABLED) { | if (lun->flags & CTL_LUN_DISABLED) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 510 Lines • ▼ Show 20 Lines | ctl_report_luns(struct ctl_scsiio *ctsio) | ||||
uint32_t initidx, targ_lun_id, lun_id; | uint32_t initidx, targ_lun_id, lun_id; | ||||
retval = CTL_RETVAL_COMPLETE; | retval = CTL_RETVAL_COMPLETE; | ||||
cdb = (struct scsi_report_luns *)ctsio->cdb; | cdb = (struct scsi_report_luns *)ctsio->cdb; | ||||
CTL_DEBUG_PRINT(("ctl_report_luns\n")); | CTL_DEBUG_PRINT(("ctl_report_luns\n")); | ||||
num_luns = 0; | num_luns = 0; | ||||
num_port_luns = port->lun_map ? port->lun_map_size : CTL_MAX_LUNS; | num_port_luns = port->lun_map ? port->lun_map_size : ctl_max_luns; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) { | for (targ_lun_id = 0; targ_lun_id < num_port_luns; targ_lun_id++) { | ||||
if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX) | if (ctl_lun_map_from_port(port, targ_lun_id) != UINT32_MAX) | ||||
num_luns++; | num_luns++; | ||||
} | } | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
switch (cdb->select_report) { | switch (cdb->select_report) { | ||||
▲ Show 20 Lines • Show All 2,173 Lines • ▼ Show 20 Lines | ctl_failover_lun(union ctl_io *rio) | ||||
struct ctl_io_hdr *io, *next_io; | struct ctl_io_hdr *io, *next_io; | ||||
uint32_t targ_lun; | uint32_t targ_lun; | ||||
targ_lun = rio->io_hdr.nexus.targ_mapped_lun; | targ_lun = rio->io_hdr.nexus.targ_mapped_lun; | ||||
CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", targ_lun)); | CTL_DEBUG_PRINT(("FAILOVER for lun %ju\n", targ_lun)); | ||||
/* Find and lock the LUN. */ | /* Find and lock the LUN. */ | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun > CTL_MAX_LUNS || | if (targ_lun > ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
return; | return; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
if (lun->flags & CTL_LUN_DISABLED) { | if (lun->flags & CTL_LUN_DISABLED) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
const struct ctl_cmd_entry *entry; | const struct ctl_cmd_entry *entry; | ||||
uint32_t initidx, targ_lun; | uint32_t initidx, targ_lun; | ||||
int retval = 0; | int retval = 0; | ||||
lun = NULL; | lun = NULL; | ||||
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; | targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; | ||||
if (targ_lun < CTL_MAX_LUNS) | if (targ_lun < ctl_max_luns) | ||||
lun = softc->ctl_luns[targ_lun]; | lun = softc->ctl_luns[targ_lun]; | ||||
if (lun) { | if (lun) { | ||||
/* | /* | ||||
* If the LUN is invalid, pretend that it doesn't exist. | * If the LUN is invalid, pretend that it doesn't exist. | ||||
* It will go away as soon as all pending I/O has been | * It will go away as soon as all pending I/O has been | ||||
* completed. | * completed. | ||||
*/ | */ | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 373 Lines • ▼ Show 20 Lines | ctl_do_lun_reset(struct ctl_lun *lun, uint32_t initidx, ctl_ua_type ua_type) | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
/* Abort tasks. */ | /* Abort tasks. */ | ||||
for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL; | for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL; | ||||
xio = (union ctl_io *)TAILQ_NEXT(&xio->io_hdr, ooa_links)) { | xio = (union ctl_io *)TAILQ_NEXT(&xio->io_hdr, ooa_links)) { | ||||
xio->io_hdr.flags |= CTL_FLAG_ABORT | CTL_FLAG_ABORT_STATUS; | xio->io_hdr.flags |= CTL_FLAG_ABORT | CTL_FLAG_ABORT_STATUS; | ||||
} | } | ||||
/* Clear CA. */ | /* Clear CA. */ | ||||
for (i = 0; i < CTL_MAX_PORTS; i++) { | for (i = 0; i < ctl_max_ports; i++) { | ||||
free(lun->pending_sense[i], M_CTL); | free(lun->pending_sense[i], M_CTL); | ||||
lun->pending_sense[i] = NULL; | lun->pending_sense[i] = NULL; | ||||
} | } | ||||
/* Clear reservation. */ | /* Clear reservation. */ | ||||
lun->flags &= ~CTL_LUN_RESERVED; | lun->flags &= ~CTL_LUN_RESERVED; | ||||
/* Clear prevent media removal. */ | /* Clear prevent media removal. */ | ||||
if (lun->prevent) { | if (lun->prevent) { | ||||
for (i = 0; i < CTL_MAX_INITIATORS; i++) | for (i = 0; i < CTL_MAX_INITIATORS; i++) | ||||
Show All 16 Lines | |||||
{ | { | ||||
struct ctl_softc *softc = CTL_SOFTC(io); | struct ctl_softc *softc = CTL_SOFTC(io); | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
uint32_t targ_lun, initidx; | uint32_t targ_lun, initidx; | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
initidx = ctl_get_initindex(&io->io_hdr.nexus); | initidx = ctl_get_initindex(&io->io_hdr.nexus); | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | ||||
return (1); | return (1); | ||||
} | } | ||||
ctl_do_lun_reset(lun, initidx, CTL_UA_LUN_RESET); | ctl_do_lun_reset(lun, initidx, CTL_UA_LUN_RESET); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_FUNCTION_COMPLETE; | io->taskio.task_status = CTL_TASK_FUNCTION_COMPLETE; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | ctl_abort_task_set(union ctl_io *io) | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
uint32_t targ_lun; | uint32_t targ_lun; | ||||
/* | /* | ||||
* Look up the LUN. | * Look up the LUN. | ||||
*/ | */ | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | ||||
return (1); | return (1); | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | #endif | ||||
found = 0; | found = 0; | ||||
/* | /* | ||||
* Look up the LUN. | * Look up the LUN. | ||||
*/ | */ | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | ||||
return (1); | return (1); | ||||
} | } | ||||
#if 0 | #if 0 | ||||
printf("ctl_abort_task: called for lun %lld, tag %d type %d\n", | printf("ctl_abort_task: called for lun %lld, tag %d type %d\n", | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | ctl_query_task(union ctl_io *io, int task_set) | ||||
struct ctl_softc *softc = CTL_SOFTC(io); | struct ctl_softc *softc = CTL_SOFTC(io); | ||||
union ctl_io *xio; | union ctl_io *xio; | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
int found = 0; | int found = 0; | ||||
uint32_t targ_lun; | uint32_t targ_lun; | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | ||||
return (1); | return (1); | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL; | for (xio = (union ctl_io *)TAILQ_FIRST(&lun->ooa_queue); xio != NULL; | ||||
Show All 22 Lines | |||||
{ | { | ||||
struct ctl_softc *softc = CTL_SOFTC(io); | struct ctl_softc *softc = CTL_SOFTC(io); | ||||
struct ctl_lun *lun; | struct ctl_lun *lun; | ||||
ctl_ua_type ua; | ctl_ua_type ua; | ||||
uint32_t targ_lun, initidx; | uint32_t targ_lun, initidx; | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | io->taskio.task_status = CTL_TASK_LUN_DOES_NOT_EXIST; | ||||
return (1); | return (1); | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
initidx = ctl_get_initindex(&io->io_hdr.nexus); | initidx = ctl_get_initindex(&io->io_hdr.nexus); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | ctl_handle_isc(union ctl_io *io) | ||||
targ_lun = io->io_hdr.nexus.targ_mapped_lun; | targ_lun = io->io_hdr.nexus.targ_mapped_lun; | ||||
switch (io->io_hdr.msg_type) { | switch (io->io_hdr.msg_type) { | ||||
case CTL_MSG_SERIALIZE: | case CTL_MSG_SERIALIZE: | ||||
ctl_serialize_other_sc_cmd(&io->scsiio); | ctl_serialize_other_sc_cmd(&io->scsiio); | ||||
break; | break; | ||||
case CTL_MSG_R2R: /* Only used in SER_ONLY mode. */ | case CTL_MSG_R2R: /* Only used in SER_ONLY mode. */ | ||||
entry = ctl_get_cmd_entry(&io->scsiio, NULL); | entry = ctl_get_cmd_entry(&io->scsiio, NULL); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
ctl_done(io); | ctl_done(io); | ||||
break; | break; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
if (ctl_scsiio_lun_check(lun, entry, &io->scsiio) != 0) { | if (ctl_scsiio_lun_check(lun, entry, &io->scsiio) != 0) { | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
ctl_done(io); | ctl_done(io); | ||||
break; | break; | ||||
} | } | ||||
io->io_hdr.flags |= CTL_FLAG_IS_WAS_ON_RTR; | io->io_hdr.flags |= CTL_FLAG_IS_WAS_ON_RTR; | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
ctl_enqueue_rtr(io); | ctl_enqueue_rtr(io); | ||||
break; | break; | ||||
case CTL_MSG_FINISH_IO: | case CTL_MSG_FINISH_IO: | ||||
if (softc->ha_mode == CTL_HA_MODE_XFER) { | if (softc->ha_mode == CTL_HA_MODE_XFER) { | ||||
ctl_done(io); | ctl_done(io); | ||||
break; | break; | ||||
} | } | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
ctl_free_io(io); | ctl_free_io(io); | ||||
break; | break; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, ooa_links); | TAILQ_REMOVE(&lun->ooa_queue, &io->io_hdr, ooa_links); | ||||
ctl_check_blocked(lun); | ctl_check_blocked(lun); | ||||
mtx_unlock(&lun->lun_lock); | mtx_unlock(&lun->lun_lock); | ||||
▲ Show 20 Lines • Show All 952 Lines • ▼ Show 20 Lines | ctl_queue_sense(union ctl_io *io) | ||||
* LUN lookup will likely move to the ctl_work_thread() once we | * LUN lookup will likely move to the ctl_work_thread() once we | ||||
* have our new queueing infrastructure (that doesn't put things on | * have our new queueing infrastructure (that doesn't put things on | ||||
* a per-LUN queue initially). That is so that we can handle | * a per-LUN queue initially). That is so that we can handle | ||||
* things like an INQUIRY to a LUN that we don't have enabled. We | * things like an INQUIRY to a LUN that we don't have enabled. We | ||||
* can't deal with that right now. | * can't deal with that right now. | ||||
* If we don't have a LUN for this, just toss the sense information. | * If we don't have a LUN for this, just toss the sense information. | ||||
*/ | */ | ||||
mtx_lock(&softc->ctl_lock); | mtx_lock(&softc->ctl_lock); | ||||
if (targ_lun >= CTL_MAX_LUNS || | if (targ_lun >= ctl_max_luns || | ||||
(lun = softc->ctl_luns[targ_lun]) == NULL) { | (lun = softc->ctl_luns[targ_lun]) == NULL) { | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
goto bailout; | goto bailout; | ||||
} | } | ||||
mtx_lock(&lun->lun_lock); | mtx_lock(&lun->lun_lock); | ||||
mtx_unlock(&softc->ctl_lock); | mtx_unlock(&softc->ctl_lock); | ||||
initidx = ctl_get_initindex(&io->io_hdr.nexus); | initidx = ctl_get_initindex(&io->io_hdr.nexus); | ||||
▲ Show 20 Lines • Show All 390 Lines • Show Last 20 Lines |
Could you add read-only (CTL_RDTUN) sysctl-s for these two, to make it possible to easily check the current values?