summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/cam_ccb.h1
-rw-r--r--sys/cam/cam_xpt.c23
-rw-r--r--sys/dev/mps/mps_sas.c480
-rw-r--r--sys/dev/mps/mps_sas.h4
-rw-r--r--sys/dev/mps/mps_sas_lsi.c3
-rw-r--r--sys/sys/param.h2
6 files changed, 198 insertions, 315 deletions
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 04ed592..4012068 100644
--- a/sys/cam/cam_ccb.h
+++ b/sys/cam/cam_ccb.h
@@ -571,6 +571,7 @@ typedef enum {
PIM_NO_6_BYTE = 0x08, /* Do not send 6-byte commands */
PIM_SEQSCAN = 0x04, /* Do bus scans sequentially, not in parallel */
PIM_UNMAPPED = 0x02,
+ PIM_NOSCAN = 0x01 /* SIM does its own scanning */
} pi_miscflag;
/* Path Inquiry CCB */
diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c
index 8f2c93e..aac1be2 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -3895,18 +3895,23 @@ xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
/* Notify interested parties */
if (sim->path_id != CAM_XPT_PATH_ID) {
- union ccb *scan_ccb;
xpt_async(AC_PATH_REGISTERED, path, &cpi);
- /* Initiate bus rescan. */
- scan_ccb = xpt_alloc_ccb_nowait();
- if (scan_ccb != NULL) {
- scan_ccb->ccb_h.path = path;
- scan_ccb->ccb_h.func_code = XPT_SCAN_BUS;
- scan_ccb->crcn.flags = 0;
- xpt_rescan(scan_ccb);
+ if ((cpi.hba_misc & PIM_NOSCAN) == 0) {
+ union ccb *scan_ccb;
+
+ /* Initiate bus rescan. */
+ scan_ccb = xpt_alloc_ccb_nowait();
+ if (scan_ccb != NULL) {
+ scan_ccb->ccb_h.path = path;
+ scan_ccb->ccb_h.func_code = XPT_SCAN_BUS;
+ scan_ccb->crcn.flags = 0;
+ xpt_rescan(scan_ccb);
+ } else
+ xpt_print(path,
+ "Can't allocate CCB to scan bus\n");
} else
- xpt_print(path, "Can't allocate CCB to scan bus\n");
+ xpt_free_path(path);
} else
xpt_free_path(path);
return (CAM_SUCCESS);
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index 80a0f52..f524c8a 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -136,14 +136,12 @@ static void mpssas_action_smpio(struct mpssas_softc *sassc, union ccb *ccb);
static void mpssas_resetdev_complete(struct mps_softc *, struct mps_command *);
static int mpssas_send_abort(struct mps_softc *sc, struct mps_command *tm, struct mps_command *cm);
static int mpssas_send_reset(struct mps_softc *sc, struct mps_command *tm, uint8_t type);
-static void mpssas_rescan(struct mpssas_softc *sassc, union ccb *ccb);
-static void mpssas_rescan_done(struct cam_periph *periph, union ccb *done_ccb);
-static void mpssas_scanner_thread(void *arg);
-#if __FreeBSD_version >= 1000006
static void mpssas_async(void *callback_arg, uint32_t code,
struct cam_path *path, void *arg);
-#else
-static void mpssas_check_eedp(struct mpssas_softc *sassc);
+#if (__FreeBSD_version < 901503) || \
+ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006))
+static void mpssas_check_eedp(struct mps_softc *sc, struct cam_path *path,
+ struct ccb_getdev *cgd);
static void mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb);
#endif
static int mpssas_send_portenable(struct mps_softc *sc);
@@ -202,8 +200,12 @@ mpssas_startup_decrement(struct mpssas_softc *sassc)
mps_dprint(sassc->sc, MPS_INIT,
"%s releasing simq\n", __func__);
sassc->flags &= ~MPSSAS_IN_STARTUP;
+#if __FreeBSD_version >= 1000039
+ xpt_release_boot();
+#else
xpt_release_simq(sassc->sim, 1);
mpssas_rescan_target(sassc->sc, NULL);
+#endif
}
mps_dprint(sassc->sc, MPS_INIT, "%s refcount %u\n", __func__,
sassc->startup_refcount);
@@ -254,7 +256,6 @@ mpssas_free_tm(struct mps_softc *sc, struct mps_command *tm)
mps_free_high_priority_command(sc, tm);
}
-
void
mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ)
{
@@ -292,7 +293,7 @@ mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ)
ccb->ccb_h.func_code = XPT_SCAN_TGT;
mps_dprint(sc, MPS_TRACE, "%s targetid %u\n", __func__, targetid);
- mpssas_rescan(sassc, ccb);
+ xpt_rescan(ccb);
}
static void
@@ -690,9 +691,7 @@ int
mps_attach_sas(struct mps_softc *sc)
{
struct mpssas_softc *sassc;
-#if __FreeBSD_version >= 1000006
cam_status status;
-#endif
int unit, error = 0;
MPS_FUNCTRACE(sc);
@@ -740,16 +739,7 @@ mps_attach_sas(struct mps_softc *sc)
taskqueue_start_threads(&sassc->ev_tq, 1, 255, "%s taskq",
device_get_nameunit(sc->mps_dev));
- TAILQ_INIT(&sassc->ccb_scanq);
- error = mps_kproc_create(mpssas_scanner_thread, sassc,
- &sassc->rescan_thread, 0, 0, "mps_scan%d", unit);
- if (error) {
- mps_printf(sc, "Error %d starting rescan thread\n", error);
- goto out;
- }
-
mps_lock(sc);
- sassc->flags |= MPSSAS_SCANTHREAD;
/*
* XXX There should be a bus for every port on the adapter, but since
@@ -764,12 +754,16 @@ mps_attach_sas(struct mps_softc *sc)
}
/*
- * Assume that discovery events will start right away. Freezing
- * the simq will prevent the CAM boottime scanner from running
- * before discovery is complete.
+ * Assume that discovery events will start right away.
+ *
+ * Hold off boot until discovery is complete.
*/
sassc->flags |= MPSSAS_IN_STARTUP | MPSSAS_IN_DISCOVERY;
+#if __FreeBSD_version >= 1000039
+ xpt_hold_boot();
+#else
xpt_freeze_simq(sassc->sim, 1);
+#endif
sc->sassc->startup_refcount = 0;
callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
@@ -777,14 +771,42 @@ mps_attach_sas(struct mps_softc *sc)
sassc->tm_count = 0;
-#if __FreeBSD_version >= 1000006
- status = xpt_register_async(AC_ADVINFO_CHANGED, mpssas_async, sc, NULL);
+ /*
+ * Register for async events so we can determine the EEDP
+ * capabilities of devices.
+ */
+ status = xpt_create_path(&sassc->path, /*periph*/NULL,
+ cam_sim_path(sc->sassc->sim), CAM_TARGET_WILDCARD,
+ CAM_LUN_WILDCARD);
if (status != CAM_REQ_CMP) {
- mps_dprint(sc, MPS_ERROR,
- "Error %#x registering async handler for "
- "AC_ADVINFO_CHANGED events\n", status);
- }
+ mps_printf(sc, "Error %#x creating sim path\n", status);
+ sassc->path = NULL;
+ } else {
+ int event;
+
+#if (__FreeBSD_version >= 1000006) || \
+ ((__FreeBSD_version >= 901503) && (__FreeBSD_version < 1000000))
+ event = AC_ADVINFO_CHANGED;
+#else
+ event = AC_FOUND_DEVICE;
#endif
+ status = xpt_register_async(event, mpssas_async, sc,
+ sassc->path);
+ if (status != CAM_REQ_CMP) {
+ mps_dprint(sc, MPS_ERROR,
+ "Error %#x registering async handler for "
+ "AC_ADVINFO_CHANGED events\n", status);
+ xpt_free_path(sassc->path);
+ sassc->path = NULL;
+ }
+ }
+ if (status != CAM_REQ_CMP) {
+ /*
+ * EEDP use is the exception, not the rule.
+ * Warn the user, but do not fail to attach.
+ */
+ mps_printf(sc, "EEDP capabilities disabled.\n");
+ }
mps_unlock(sc);
@@ -823,9 +845,11 @@ mps_detach_sas(struct mps_softc *sc)
mps_lock(sc);
/* Deregister our async handler */
-#if __FreeBSD_version >= 1000006
- xpt_register_async(0, mpssas_async, sc, NULL);
-#endif
+ if (sassc->path != NULL) {
+ xpt_register_async(0, mpssas_async, sc, sassc->path);
+ xpt_free_path(sassc->path);
+ sassc->path = NULL;
+ }
if (sassc->flags & MPSSAS_IN_STARTUP)
xpt_release_simq(sassc->sim, 1);
@@ -835,15 +859,7 @@ mps_detach_sas(struct mps_softc *sc)
cam_sim_free(sassc->sim, FALSE);
}
- if (sassc->flags & MPSSAS_SCANTHREAD) {
- sassc->flags |= MPSSAS_SHUTDOWN;
- wakeup(&sassc->ccb_scanq);
-
- if (sassc->flags & MPSSAS_SCANTHREAD) {
- msleep(&sassc->flags, &sc->mps_mtx, PRIBIO,
- "mps_shutdown", 30 * hz);
- }
- }
+ sassc->flags |= MPSSAS_SHUTDOWN;
mps_unlock(sc);
if (sassc->devq != NULL)
@@ -934,7 +950,11 @@ mpssas_action(struct cam_sim *sim, union ccb *ccb)
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
cpi->target_sprt = 0;
+#if __FreeBSD_version >= 1000039
+ cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED | PIM_NOSCAN;
+#else
cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
+#endif
cpi->hba_eng_cnt = 0;
cpi->max_target = sassc->sc->facts->MaxTargets - 1;
cpi->max_lun = 255;
@@ -3126,114 +3146,6 @@ mpssas_poll(struct cam_sim *sim)
}
static void
-mpssas_rescan_done(struct cam_periph *periph, union ccb *done_ccb)
-{
- struct mpssas_softc *sassc;
- char path_str[64];
-
- if (done_ccb == NULL)
- return;
-
- sassc = (struct mpssas_softc *)done_ccb->ccb_h.ppriv_ptr1;
-
- mtx_assert(&sassc->sc->mps_mtx, MA_OWNED);
-
- xpt_path_string(done_ccb->ccb_h.path, path_str, sizeof(path_str));
- mps_dprint(sassc->sc, MPS_XINFO, "Completing rescan for %s\n", path_str);
-
- xpt_free_path(done_ccb->ccb_h.path);
- xpt_free_ccb(done_ccb);
-
-#if __FreeBSD_version < 1000006
- /*
- * Before completing scan, get EEDP stuff for all of the existing
- * targets.
- */
- mpssas_check_eedp(sassc);
-#endif
-
-}
-
-/* thread to handle bus rescans */
-static void
-mpssas_scanner_thread(void *arg)
-{
- struct mpssas_softc *sassc;
- struct mps_softc *sc;
- union ccb *ccb;
-
- sassc = (struct mpssas_softc *)arg;
- sc = sassc->sc;
-
- MPS_FUNCTRACE(sc);
-
- mps_lock(sc);
- for (;;) {
- /* Sleep for 1 second and check the queue status*/
- msleep(&sassc->ccb_scanq, &sc->mps_mtx, PRIBIO,
- "mps_scanq", 1 * hz);
- if (sassc->flags & MPSSAS_SHUTDOWN) {
- mps_dprint(sc, MPS_XINFO, "Scanner shutting down\n");
- break;
- }
-next_work:
- // Get first work.
- ccb = (union ccb *)TAILQ_FIRST(&sassc->ccb_scanq);
- if (ccb == NULL)
- continue;
- // Got first work.
- TAILQ_REMOVE(&sassc->ccb_scanq, &ccb->ccb_h, sim_links.tqe);
- xpt_action(ccb);
- if (sassc->flags & MPSSAS_SHUTDOWN) {
- mps_dprint(sc, MPS_XINFO, "Scanner shutting down\n");
- break;
- }
- goto next_work;
- }
-
- sassc->flags &= ~MPSSAS_SCANTHREAD;
- wakeup(&sassc->flags);
- mps_unlock(sc);
- mps_dprint(sc, MPS_TRACE, "Scanner exiting\n");
- mps_kproc_exit(0);
-}
-
-/*
- * This function will send READ_CAP_16 to find out EEDP protection mode.
- * It will check inquiry data before sending READ_CAP_16.
- * Callback for READ_CAP_16 is "mpssas_read_cap_done".
- * This is insternal scsi command and we need to take care release of devq, if
- * CAM_DEV_QFRZN is set. Driver needs to release devq if it has frozen any.
- * xpt_release_devq is called from mpssas_read_cap_done.
- *
- * All other commands will be handled by periph layer and there it will
- * check for "CAM_DEV_QFRZN" and release of devq will be done.
- */
-static void
-mpssas_rescan(struct mpssas_softc *sassc, union ccb *ccb)
-{
- char path_str[64];
-
- MPS_FUNCTRACE(sassc->sc);
-
- mtx_assert(&sassc->sc->mps_mtx, MA_OWNED);
-
- if (ccb == NULL)
- return;
-
- xpt_path_string(ccb->ccb_h.path, path_str, sizeof(path_str));
- mps_dprint(sassc->sc, MPS_XINFO, "Queueing rescan for %s\n", path_str);
-
- /* Prepare request */
- ccb->ccb_h.ppriv_ptr1 = sassc;
- ccb->ccb_h.cbfcnp = mpssas_rescan_done;
- xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, MPS_PRIORITY_XPT);
- TAILQ_INSERT_TAIL(&sassc->ccb_scanq, &ccb->ccb_h, sim_links.tqe);
- wakeup(&sassc->ccb_scanq);
-}
-
-#if __FreeBSD_version >= 1000006
-static void
mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
void *arg)
{
@@ -3242,6 +3154,8 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
sc = (struct mps_softc *)callback_arg;
switch (code) {
+#if (__FreeBSD_version >= 1000006) || \
+ ((__FreeBSD_version >= 901503) && (__FreeBSD_version < 1000000))
case AC_ADVINFO_CHANGED: {
struct mpssas_target *target;
struct mpssas_softc *sassc;
@@ -3264,13 +3178,6 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
break;
/*
- * We're only interested in devices that are attached to
- * this controller.
- */
- if (xpt_path_path_id(path) != sassc->sim->path_id)
- break;
-
- /*
* We should have a handle for this, but check to make sure.
*/
target = &sassc->targets[xpt_path_target_id(path)];
@@ -3321,177 +3228,147 @@ mpssas_async(void *callback_arg, uint32_t code, struct cam_path *path,
}
break;
}
+#else
+ case AC_FOUND_DEVICE: {
+ struct ccb_getdev *cgd;
+
+ cgd = arg;
+ mpssas_check_eedp(sc, path, cgd);
+ break;
+ }
+#endif
default:
break;
}
}
-#else /* __FreeBSD_version >= 1000006 */
+#if (__FreeBSD_version < 901503) || \
+ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006))
static void
-mpssas_check_eedp(struct mpssas_softc *sassc)
+mpssas_check_eedp(struct mps_softc *sc, struct cam_path *path,
+ struct ccb_getdev *cgd)
{
- struct mps_softc *sc = sassc->sc;
+ struct mpssas_softc *sassc = sc->sassc;
struct ccb_scsiio *csio;
struct scsi_read_capacity_16 *scsi_cmd;
struct scsi_read_capacity_eedp *rcap_buf;
- union ccb *ccb;
- path_id_t pathid = cam_sim_path(sassc->sim);
+ path_id_t pathid;
target_id_t targetid;
lun_id_t lunid;
- struct cam_periph *found_periph;
+ union ccb *ccb;
+ struct cam_path *local_path;
struct mpssas_target *target;
struct mpssas_lun *lun;
uint8_t found_lun;
- struct ccb_getdev cgd;
char path_str[64];
- /*
- * Issue a READ CAPACITY 16 command to each LUN of each target. This
- * info is used to determine if the LUN is formatted for EEDP support.
- */
- for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) {
- target = &sassc->targets[targetid];
- if (target->handle == 0x0) {
- continue;
- }
+ sassc = sc->sassc;
+ pathid = cam_sim_path(sassc->sim);
+ targetid = xpt_path_target_id(path);
+ lunid = xpt_path_lun_id(path);
- lunid = 0;
- do {
- ccb = xpt_alloc_ccb_nowait();
- if (ccb == NULL) {
- mps_dprint(sc, MPS_ERROR, "Unable to alloc CCB "
- "for EEDP support.\n");
- return;
- }
+ target = &sassc->targets[targetid];
+ if (target->handle == 0x0)
+ return;
- if (xpt_create_path(&ccb->ccb_h.path, NULL,
- pathid, targetid, lunid) != CAM_REQ_CMP) {
- mps_dprint(sc, MPS_ERROR, "Unable to create "
- "path for EEDP support\n");
- xpt_free_ccb(ccb);
- return;
- }
+ /*
+ * Determine if the device is EEDP capable.
+ *
+ * If this flag is set in the inquiry data,
+ * the device supports protection information,
+ * and must support the 16 byte read
+ * capacity command, otherwise continue without
+ * sending read cap 16
+ */
+ if ((cgd->inq_data.spc3_flags & SPC3_SID_PROTECT) == 0)
+ return;
- /*
- * If a periph is returned, the LUN exists. Create an
- * entry in the target's LUN list.
- */
- if ((found_periph = cam_periph_find(ccb->ccb_h.path,
- NULL)) != NULL) {
- /*
- * If LUN is already in list, don't create a new
- * one.
- */
- found_lun = FALSE;
- SLIST_FOREACH(lun, &target->luns, lun_link) {
- if (lun->lun_id == lunid) {
- found_lun = TRUE;
- break;
- }
- }
- if (!found_lun) {
- lun = malloc(sizeof(struct mpssas_lun),
- M_MPT2, M_NOWAIT | M_ZERO);
- if (lun == NULL) {
- mps_dprint(sc, MPS_ERROR,
- "Unable to alloc LUN for "
- "EEDP support.\n");
- xpt_free_path(ccb->ccb_h.path);
- xpt_free_ccb(ccb);
- return;
- }
- lun->lun_id = lunid;
- SLIST_INSERT_HEAD(&target->luns, lun,
- lun_link);
- }
- lunid++;
- /* Before Issuing READ CAPACITY 16,
- * check Device type.
- */
- xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path,
- CAM_PRIORITY_NORMAL);
- cgd.ccb_h.func_code = XPT_GDEV_TYPE;
- xpt_action((union ccb *)&cgd);
+ /*
+ * Issue a READ CAPACITY 16 command. This info
+ * is used to determine if the LUN is formatted
+ * for EEDP support.
+ */
+ ccb = xpt_alloc_ccb_nowait();
+ if (ccb == NULL) {
+ mps_dprint(sc, MPS_ERROR, "Unable to alloc CCB "
+ "for EEDP support.\n");
+ return;
+ }
- /*
- * If this flag is set in the inquiry data,
- * the device supports protection information,
- * and must support the 16 byte read
- * capacity command, otherwise continue without
- * sending read cap 16
- */
+ if (xpt_create_path(&local_path, xpt_periph,
+ pathid, targetid, lunid) != CAM_REQ_CMP) {
+ mps_dprint(sc, MPS_ERROR, "Unable to create "
+ "path for EEDP support\n");
+ xpt_free_ccb(ccb);
+ return;
+ }
- xpt_path_string(ccb->ccb_h.path, path_str,
- sizeof(path_str));
+ /*
+ * If LUN is already in list, don't create a new
+ * one.
+ */
+ found_lun = FALSE;
+ SLIST_FOREACH(lun, &target->luns, lun_link) {
+ if (lun->lun_id == lunid) {
+ found_lun = TRUE;
+ break;
+ }
+ }
+ if (!found_lun) {
+ lun = malloc(sizeof(struct mpssas_lun), M_MPT2,
+ M_NOWAIT | M_ZERO);
+ if (lun == NULL) {
+ mps_dprint(sc, MPS_ERROR,
+ "Unable to alloc LUN for EEDP support.\n");
+ xpt_free_path(local_path);
+ xpt_free_ccb(ccb);
+ return;
+ }
+ lun->lun_id = lunid;
+ SLIST_INSERT_HEAD(&target->luns, lun,
+ lun_link);
+ }
- if ((cgd.inq_data.spc3_flags &
- SPC3_SID_PROTECT) == 0) {
- xpt_free_path(ccb->ccb_h.path);
- xpt_free_ccb(ccb);
- continue;
- }
-
- mps_dprint(sc, MPS_XINFO,
- "Sending read cap: path %s"
- " handle %d\n", path_str, target->handle );
-
- /*
- * Issue a READ CAPACITY 16 command for the LUN.
- * The mpssas_read_cap_done function will load
- * the read cap info into the LUN struct.
- */
- rcap_buf =
- malloc(sizeof(struct scsi_read_capacity_eedp),
- M_MPT2, M_NOWAIT| M_ZERO);
- if (rcap_buf == NULL) {
- mps_dprint(sc, MPS_ERROR, "Unable to alloc read "
- "capacity buffer for EEDP support.\n");
- xpt_free_path(ccb->ccb_h.path);
- xpt_free_ccb(ccb);
- return;
- }
- csio = &ccb->csio;
- csio->ccb_h.func_code = XPT_SCSI_IO;
- csio->ccb_h.flags = CAM_DIR_IN;
- csio->ccb_h.retry_count = 4;
- csio->ccb_h.cbfcnp = mpssas_read_cap_done;
- csio->ccb_h.timeout = 60000;
- csio->data_ptr = (uint8_t *)rcap_buf;
- csio->dxfer_len = sizeof(struct
- scsi_read_capacity_eedp);
- csio->sense_len = MPS_SENSE_LEN;
- csio->cdb_len = sizeof(*scsi_cmd);
- csio->tag_action = MSG_SIMPLE_Q_TAG;
-
- scsi_cmd = (struct scsi_read_capacity_16 *)
- &csio->cdb_io.cdb_bytes;
- bzero(scsi_cmd, sizeof(*scsi_cmd));
- scsi_cmd->opcode = 0x9E;
- scsi_cmd->service_action = SRC16_SERVICE_ACTION;
- ((uint8_t *)scsi_cmd)[13] = sizeof(struct
- scsi_read_capacity_eedp);
+ xpt_path_string(local_path, path_str, sizeof(path_str));
+ mps_dprint(sc, MPS_INFO, "Sending read cap: path %s handle %d\n",
+ path_str, target->handle);
- /*
- * Set the path, target and lun IDs for the READ
- * CAPACITY request.
- */
- ccb->ccb_h.path_id =
- xpt_path_path_id(ccb->ccb_h.path);
- ccb->ccb_h.target_id =
- xpt_path_target_id(ccb->ccb_h.path);
- ccb->ccb_h.target_lun =
- xpt_path_lun_id(ccb->ccb_h.path);
-
- ccb->ccb_h.ppriv_ptr1 = sassc;
- xpt_action(ccb);
- } else {
- xpt_free_path(ccb->ccb_h.path);
- xpt_free_ccb(ccb);
- }
- } while (found_periph);
+ /*
+ * Issue a READ CAPACITY 16 command for the LUN.
+ * The mpssas_read_cap_done function will load
+ * the read cap info into the LUN struct.
+ */
+ rcap_buf = malloc(sizeof(struct scsi_read_capacity_eedp),
+ M_MPT2, M_NOWAIT | M_ZERO);
+ if (rcap_buf == NULL) {
+ mps_dprint(sc, MPS_FAULT,
+ "Unable to alloc read capacity buffer for EEDP support.\n");
+ xpt_free_path(ccb->ccb_h.path);
+ xpt_free_ccb(ccb);
+ return;
}
-}
+ xpt_setup_ccb(&ccb->ccb_h, local_path, CAM_PRIORITY_XPT);
+ csio = &ccb->csio;
+ csio->ccb_h.func_code = XPT_SCSI_IO;
+ csio->ccb_h.flags = CAM_DIR_IN;
+ csio->ccb_h.retry_count = 4;
+ csio->ccb_h.cbfcnp = mpssas_read_cap_done;
+ csio->ccb_h.timeout = 60000;
+ csio->data_ptr = (uint8_t *)rcap_buf;
+ csio->dxfer_len = sizeof(struct scsi_read_capacity_eedp);
+ csio->sense_len = MPS_SENSE_LEN;
+ csio->cdb_len = sizeof(*scsi_cmd);
+ csio->tag_action = MSG_SIMPLE_Q_TAG;
+
+ scsi_cmd = (struct scsi_read_capacity_16 *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = 0x9E;
+ scsi_cmd->service_action = SRC16_SERVICE_ACTION;
+ ((uint8_t *)scsi_cmd)[13] = sizeof(struct scsi_read_capacity_eedp);
+ ccb->ccb_h.ppriv_ptr1 = sassc;
+ xpt_action(ccb);
+}
static void
mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
@@ -3556,7 +3433,8 @@ mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
xpt_free_path(done_ccb->ccb_h.path);
xpt_free_ccb(done_ccb);
}
-#endif /* __FreeBSD_version >= 1000006 */
+#endif /* (__FreeBSD_version < 901503) || \
+ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) */
int
mpssas_startup(struct mps_softc *sc)
diff --git a/sys/dev/mps/mps_sas.h b/sys/dev/mps/mps_sas.h
index 6857b98..662a29a 100644
--- a/sys/dev/mps/mps_sas.h
+++ b/sys/dev/mps/mps_sas.h
@@ -87,7 +87,6 @@ struct mpssas_softc {
#define MPSSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2)
#define MPSSAS_QUEUE_FROZEN (1 << 3)
#define MPSSAS_SHUTDOWN (1 << 4)
-#define MPSSAS_SCANTHREAD (1 << 5)
struct mpssas_target *targets;
struct cam_devq *devq;
struct cam_sim *sim;
@@ -101,9 +100,6 @@ struct mpssas_softc {
u_int tm_count;
struct proc *sysctl_proc;
- TAILQ_HEAD(, ccb_hdr) ccb_scanq;
- struct proc *rescan_thread;
-
struct taskqueue *ev_tq;
struct task ev_task;
TAILQ_HEAD(, mps_fw_event_work) ev_queue;
diff --git a/sys/dev/mps/mps_sas_lsi.c b/sys/dev/mps/mps_sas_lsi.c
index 18450ab..e056590 100644
--- a/sys/dev/mps/mps_sas_lsi.c
+++ b/sys/dev/mps/mps_sas_lsi.c
@@ -699,7 +699,10 @@ mpssas_add_device(struct mps_softc *sc, u16 handle, u8 linkrate){
mps_dprint(sc, MPS_MAPPING, "Found device <%s> <%s> <0x%04x> <%d/%d>\n", devstring,
mps_describe_table(mps_linkrate_names, targ->linkrate),
targ->handle, targ->encl_handle, targ->encl_slot);
+
+#if __FreeBSD_version < 1000039
if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
+#endif
mpssas_rescan_target(sc, targ);
mps_dprint(sc, MPS_MAPPING, "Target id 0x%x added\n", targ->tid);
out:
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 8957516..fd8b507 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1000038 /* Master, propagated to newvers */
+#define __FreeBSD_version 1000039 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
OpenPOWER on IntegriCloud