Index: sys/dev/ciss/ciss.c =================================================================== --- sys/dev/ciss/ciss.c +++ sys/dev/ciss/ciss.c @@ -242,15 +242,39 @@ .d_name = "ciss", }; +SYSCTL_NODE(_hw, OID_AUTO, ciss, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "CISS sysctl tunables"); + +/* + * This tunable can be used to force a specific initiator id + */ +static int ciss_initiator_id = CAM_TARGET_WILDCARD; +SYSCTL_INT(_hw_ciss, OID_AUTO, initiator_id, CTLFLAG_RDTUN, + &ciss_initiator_id, 0, + "force a specific initiator id"); + +/* + * This tunable can be used to force a specific initiator id + */ +static int ciss_base_transfer_speed = 132 * 1024; +SYSCTL_INT(_hw_ciss, OID_AUTO, base_transfer_speed, CTLFLAG_RDTUN, + &ciss_base_transfer_speed, 0, + "force a specific base transfer_speed"); + /* * This tunable can be set at boot time and controls whether physical devices * that are marked hidden by the firmware should be exposed anyways. */ static unsigned int ciss_expose_hidden_physical = 0; TUNABLE_INT("hw.ciss.expose_hidden_physical", &ciss_expose_hidden_physical); +SYSCTL_INT(_hw_ciss, OID_AUTO, expose_hidden_physical, CTLFLAG_RWTUN, + &ciss_expose_hidden_physical, 0, + "expose hidden physical drives"); static unsigned int ciss_nop_message_heartbeat = 0; TUNABLE_INT("hw.ciss.nop_message_heartbeat", &ciss_nop_message_heartbeat); +SYSCTL_INT(_hw_ciss, OID_AUTO, nop_message_heartbeat, CTLFLAG_RWTUN, + &ciss_nop_message_heartbeat, 0, + "nop heartbeat messages"); /* * This tunable can force a particular transport to be used: @@ -260,6 +284,9 @@ */ static int ciss_force_transport = 0; TUNABLE_INT("hw.ciss.force_transport", &ciss_force_transport); +SYSCTL_INT(_hw_ciss, OID_AUTO, force_transport, CTLFLAG_RDTUN, + &ciss_force_transport, 0, + "use default (0), force simple (1) or force performant (2) transport"); /* * This tunable can force a particular interrupt delivery method to be used: @@ -269,6 +296,9 @@ */ static int ciss_force_interrupt = 0; TUNABLE_INT("hw.ciss.force_interrupt", &ciss_force_interrupt); +SYSCTL_INT(_hw_ciss, OID_AUTO, force_interrupt, CTLFLAG_RDTUN, + &ciss_force_interrupt, 0, + "use default (0), force INTx (1) or force MSIx(2) interrupts"); /************************************************************************ * CISS adapters amazingly don't have a defined programming interface @@ -1506,6 +1536,9 @@ nphys, (nphys > 1 || nphys == 0) ? "s" : ""); } + /* Per-controller highest target number seen */ + sc->ciss_max_physical_target = 0; + /* * Figure out the bus mapping. * Logical buses include both the local logical bus for local arrays and @@ -1588,6 +1621,8 @@ } ciss_filter_physical(sc, cll); + if (bootverbose) + ciss_printf(sc, "max physical target id: %d\n", sc->ciss_max_physical_target); out: if (cll != NULL) @@ -1637,6 +1672,10 @@ target = CISS_EXTRA_TARGET2(ea); sc->ciss_physical[bus][target].cp_address = cll->lun[i]; sc->ciss_physical[bus][target].cp_online = 1; + + if ((target > sc->ciss_max_physical_target) && + (cll->lun[i].physical.mode != CISS_HDR_ADDRESS_MODE_MASK_PERIPHERAL)) + sc->ciss_max_physical_target = target; } return (0); @@ -2333,10 +2372,12 @@ *scsi_status = -1; } } - if (bootverbose && ce->command_status != CISS_CMD_STATUS_DATA_UNDERRUN) - ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x\n", + if (bootverbose && ce->command_status != CISS_CMD_STATUS_DATA_UNDERRUN) { + ciss_printf(cr->cr_sc, "command status 0x%x (%s) scsi status 0x%x (opcode 0x%02x)\n", ce->command_status, ciss_name_command_status(ce->command_status), - ce->scsi_status); + ce->scsi_status, + cc->cdb.cdb[0]); + } if (ce->command_status == CISS_CMD_STATUS_INVALID_COMMAND) { ciss_printf(cr->cr_sc, "invalid command, offense size %d at %d, value 0x%x, function %s\n", ce->additional_error_info.invalid_command.offense_size, @@ -3020,15 +3061,15 @@ cpi->hba_inquiry = PI_TAG_ABLE; /* XXX is this correct? */ cpi->target_sprt = 0; cpi->hba_misc = 0; - cpi->max_target = sc->ciss_cfg->max_logical_supported; + cpi->max_target = MAX(sc->ciss_max_physical_target, sc->ciss_cfg->max_logical_supported); cpi->max_lun = 0; /* 'logical drive' channel only */ - cpi->initiator_id = sc->ciss_cfg->max_logical_supported; + cpi->initiator_id = ciss_initiator_id; strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strlcpy(cpi->hba_vid, "CISS", HBA_IDLEN); strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 132 * 1024; /* XXX what to set this to? */ + cpi->base_transfer_speed = ciss_base_transfer_speed; cpi->transport = XPORT_SPI; cpi->transport_version = 2; cpi->protocol = PROTO_SCSI; @@ -4145,8 +4186,13 @@ cr = ciss_dequeue_notify(sc); - if (cr == NULL) - panic("cr null"); + if (cr == NULL) { + /* + * We get a NULL message sometimes when unplugging/replugging stuff + */ + continue; + } + cn = (struct ciss_notify *)cr->cr_data; switch (cn->class) { Index: sys/dev/ciss/cissvar.h =================================================================== --- sys/dev/ciss/cissvar.h +++ sys/dev/ciss/cissvar.h @@ -184,7 +184,7 @@ { /* bus connections */ device_t ciss_dev; /* bus attachment */ - struct cdev *ciss_dev_t; /* control device */ + struct cdev *ciss_dev_t; /* control device */ struct resource *ciss_regs_resource; /* register interface window */ int ciss_regs_rid; /* resource ID */ @@ -236,6 +236,7 @@ int ciss_max_bus_number; /* maximum bus number */ int ciss_max_logical_bus; int ciss_max_physical_bus; + int ciss_max_physical_target; /* highest physical target number */ struct cam_devq *ciss_cam_devq; struct cam_sim **ciss_cam_sim;