svn commit: r253550 - head/sys/dev/mps
Kenneth D. Merry
ken at FreeBSD.org
Mon Aug 12 19:02:33 UTC 2013
On Mon, Aug 12, 2013 at 21:45:45 +0400, Slawa Olhovchenkov wrote:
> On Mon, Aug 12, 2013 at 09:56:48AM -0600, Kenneth D. Merry wrote:
>
> > On Sat, Aug 10, 2013 at 22:14:54 +0400, Slawa Olhovchenkov wrote:
> > > On Mon, Jul 22, 2013 at 06:41:54PM +0000, Kenneth D. Merry wrote:
> > >
> > > > Author: ken
> > > > Date: Mon Jul 22 18:41:53 2013
> > > > New Revision: 253550
> > > > URL: http://svnweb.freebsd.org/changeset/base/253550
> > > >
> > > > Log:
> > > > Merge in phase 14+ -> 16 mps driver fixes from LSI:
> > > > Submitted by: LSI
> > > > MFC after: 1 week
> > >
> > > Not done?
> >
> > I was waiting for the stable/9 freeze to end.
>
> Hm?
>
> Date: Mon Aug 5 23:34:35 2013
> New Revision: 253975
> URL: http://svnweb.freebsd.org/changeset/base/253975
>
> Log:
> stable/9 no longer requires re@ approval for commits, now that the
> releng/9.2 branch is created.
>
> Committers are urged to exercise caution with commits to stable/9
> until the 9.2-RELEASE is finalized.
>
> Or, can you published patch for 9-STABLE?
If you really want one now, I've attached a patch from stable/9 on June
27th. It may or may not apply now.
> > Now that it's done, I hope to merge that change to stable/9 this week.
>
> Also, I see strange behaviour of LSI 9211-8i -- after some activity
> got timeout and HBA put in looped reset.
That's not good. Try with the newer driver and see whether if affects the
behavior.
Ken
--
Kenneth Merry
ken at FreeBSD.ORG
-------------- next part --------------
*** src/sys/cam/cam_ccb.h.orig
--- src/sys/cam/cam_ccb.h
***************
*** 578,583 ****
--- 578,584 ----
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 */
*** src/sys/cam/cam_xpt.c.orig
--- src/sys/cam/cam_xpt.c
***************
*** 4012,4026 ****
/* 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();
! 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_free_path(path);
return (CAM_SUCCESS);
--- 4012,4030 ----
/* Notify interested parties */
if (sim->path_id != CAM_XPT_PATH_ID) {
xpt_async(AC_PATH_REGISTERED, path, &cpi);
!
! if ((cpi.hba_misc & PIM_NOSCAN) == 0) {
! union ccb *scan_ccb;
!
! /* Initiate bus rescan. */
! scan_ccb = xpt_alloc_ccb_nowait();
! 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_free_path(path);
return (CAM_SUCCESS);
*** src/sys/dev/mps/mps.c.orig
--- src/sys/dev/mps/mps.c
***************
*** 51,56 ****
--- 51,57 ----
#include <sys/sysctl.h>
#include <sys/queue.h>
#include <sys/kthread.h>
+ #include <sys/taskqueue.h>
#include <sys/endian.h>
#include <sys/eventhandler.h>
***************
*** 61,66 ****
--- 62,68 ----
#include <dev/pci/pcivar.h>
+ #include <cam/cam.h>
#include <cam/scsi/scsi_all.h>
#include <dev/mps/mpi/mpi2_type.h>
***************
*** 73,85 ****
--- 75,93 ----
#include <dev/mps/mps_ioctl.h>
#include <dev/mps/mpsvar.h>
#include <dev/mps/mps_table.h>
+ #include <dev/mps/mps_sas.h>
static int mps_diag_reset(struct mps_softc *sc, int sleep_flag);
static int mps_init_queues(struct mps_softc *sc);
static int mps_message_unit_reset(struct mps_softc *sc, int sleep_flag);
static int mps_transition_operational(struct mps_softc *sc);
+ static int mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching);
+ static void mps_iocfacts_free(struct mps_softc *sc);
static void mps_startup(void *arg);
static int mps_send_iocinit(struct mps_softc *sc);
+ static int mps_alloc_queues(struct mps_softc *sc);
+ static int mps_alloc_replies(struct mps_softc *sc);
+ static int mps_alloc_requests(struct mps_softc *sc);
static int mps_attach_log(struct mps_softc *sc);
static __inline void mps_complete_command(struct mps_command *cm);
static void mps_dispatch_event(struct mps_softc *sc, uintptr_t data,
***************
*** 88,93 ****
--- 96,102 ----
static void mps_periodic(void *);
static int mps_reregister_events(struct mps_softc *sc);
static void mps_enqueue_request(struct mps_softc *sc, struct mps_command *cm);
+ static int mps_get_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts);
static int mps_wait_db_ack(struct mps_softc *sc, int timeout, int sleep_flag);
SYSCTL_NODE(_hw, OID_AUTO, mps, CTLFLAG_RD, 0, "MPS Driver Parameters");
***************
*** 148,154 ****
mpt2_reset_magic[i]);
/* wait 100 msec */
if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP)
! msleep(&sc->msleep_fake_chan, &sc->mps_mtx, 0, "mpsdiag", hz/10);
else if (sleep_flag == CAN_SLEEP)
pause("mpsdiag", hz/10);
else
--- 157,164 ----
mpt2_reset_magic[i]);
/* wait 100 msec */
if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP)
! msleep(&sc->msleep_fake_chan, &sc->mps_mtx, 0,
! "mpsdiag", hz/10);
else if (sleep_flag == CAN_SLEEP)
pause("mpsdiag", hz/10);
else
***************
*** 172,178 ****
for (i = 0; i < 60000; i++) {
/* wait 50 msec */
if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP)
! msleep(&sc->msleep_fake_chan, &sc->mps_mtx, 0, "mpsdiag", hz/20);
else if (sleep_flag == CAN_SLEEP)
pause("mpsdiag", hz/20);
else
--- 182,189 ----
for (i = 0; i < 60000; i++) {
/* wait 50 msec */
if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP)
! msleep(&sc->msleep_fake_chan, &sc->mps_mtx, 0,
! "mpsdiag", hz/20);
else if (sleep_flag == CAN_SLEEP)
pause("mpsdiag", hz/20);
else
***************
*** 302,310 ****
return (error);
}
/*
- * XXX Some of this should probably move to mps.c
- *
* The terms diag reset and hard reset are used interchangeably in the MPI
* docs to mean resetting the controller chip. In this code diag reset
* cleans everything up, and the hard reset function just sends the reset
--- 313,669 ----
return (error);
}
+ /*
+ * This is called during attach and when re-initializing due to a Diag Reset.
+ * IOC Facts is used to allocate many of the structures needed by the driver.
+ * If called from attach, de-allocation is not required because the driver has
+ * not allocated any structures yet, but if called from a Diag Reset, previously
+ * allocated structures based on IOC Facts will need to be freed and re-
+ * allocated bases on the latest IOC Facts.
+ */
+ static int
+ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching)
+ {
+ int error, i;
+ Mpi2IOCFactsReply_t saved_facts;
+ uint8_t saved_mode, reallocating;
+ struct mpssas_lun *lun, *lun_tmp;
+ struct mpssas_target *targ;
+
+ mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+
+ /* Save old IOC Facts and then only reallocate if Facts have changed */
+ if (!attaching) {
+ bcopy(sc->facts, &saved_facts, sizeof(MPI2_IOC_FACTS_REPLY));
+ }
+
+ /*
+ * Get IOC Facts. In all cases throughout this function, panic if doing
+ * a re-initialization and only return the error if attaching so the OS
+ * can handle it.
+ */
+ if ((error = mps_get_iocfacts(sc, sc->facts)) != 0) {
+ if (attaching) {
+ mps_dprint(sc, MPS_FAULT, "%s failed to get IOC Facts "
+ "with error %d\n", __func__, error);
+ return (error);
+ } else {
+ panic("%s failed to get IOC Facts with error %d\n",
+ __func__, error);
+ }
+ }
+
+ mps_print_iocfacts(sc, sc->facts);
+
+ snprintf(sc->fw_version, sizeof(sc->fw_version),
+ "%02d.%02d.%02d.%02d",
+ sc->facts->FWVersion.Struct.Major,
+ sc->facts->FWVersion.Struct.Minor,
+ sc->facts->FWVersion.Struct.Unit,
+ sc->facts->FWVersion.Struct.Dev);
+
+ mps_printf(sc, "Firmware: %s, Driver: %s\n", sc->fw_version,
+ MPS_DRIVER_VERSION);
+ mps_printf(sc, "IOCCapabilities: %b\n", sc->facts->IOCCapabilities,
+ "\20" "\3ScsiTaskFull" "\4DiagTrace" "\5SnapBuf" "\6ExtBuf"
+ "\7EEDP" "\10BiDirTarg" "\11Multicast" "\14TransRetry" "\15IR"
+ "\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc");
+
+ /*
+ * If the chip doesn't support event replay then a hard reset will be
+ * required to trigger a full discovery. Do the reset here then
+ * retransition to Ready. A hard reset might have already been done,
+ * but it doesn't hurt to do it again. Only do this if attaching, not
+ * for a Diag Reset.
+ */
+ if (attaching) {
+ if ((sc->facts->IOCCapabilities &
+ MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) == 0) {
+ mps_diag_reset(sc, NO_SLEEP);
+ if ((error = mps_transition_ready(sc)) != 0) {
+ mps_dprint(sc, MPS_FAULT, "%s failed to "
+ "transition to ready with error %d\n",
+ __func__, error);
+ return (error);
+ }
+ }
+ }
+
+ /*
+ * Set flag if IR Firmware is loaded. If the RAID Capability has
+ * changed from the previous IOC Facts, log a warning, but only if
+ * checking this after a Diag Reset and not during attach.
+ */
+ saved_mode = sc->ir_firmware;
+ if (sc->facts->IOCCapabilities &
+ MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)
+ sc->ir_firmware = 1;
+ if (!attaching) {
+ if (sc->ir_firmware != saved_mode) {
+ mps_dprint(sc, MPS_FAULT, "%s new IR/IT mode in IOC "
+ "Facts does not match previous mode\n", __func__);
+ }
+ }
+
+ /* Only deallocate and reallocate if relevant IOC Facts have changed */
+ reallocating = FALSE;
+ if ((!attaching) &&
+ ((saved_facts.MsgVersion != sc->facts->MsgVersion) ||
+ (saved_facts.HeaderVersion != sc->facts->HeaderVersion) ||
+ (saved_facts.MaxChainDepth != sc->facts->MaxChainDepth) ||
+ (saved_facts.RequestCredit != sc->facts->RequestCredit) ||
+ (saved_facts.ProductID != sc->facts->ProductID) ||
+ (saved_facts.IOCCapabilities != sc->facts->IOCCapabilities) ||
+ (saved_facts.IOCRequestFrameSize !=
+ sc->facts->IOCRequestFrameSize) ||
+ (saved_facts.MaxTargets != sc->facts->MaxTargets) ||
+ (saved_facts.MaxSasExpanders != sc->facts->MaxSasExpanders) ||
+ (saved_facts.MaxEnclosures != sc->facts->MaxEnclosures) ||
+ (saved_facts.HighPriorityCredit != sc->facts->HighPriorityCredit) ||
+ (saved_facts.MaxReplyDescriptorPostQueueDepth !=
+ sc->facts->MaxReplyDescriptorPostQueueDepth) ||
+ (saved_facts.ReplyFrameSize != sc->facts->ReplyFrameSize) ||
+ (saved_facts.MaxVolumes != sc->facts->MaxVolumes) ||
+ (saved_facts.MaxPersistentEntries !=
+ sc->facts->MaxPersistentEntries))) {
+ reallocating = TRUE;
+ }
+
+ /*
+ * Some things should be done if attaching or re-allocating after a Diag
+ * Reset, but are not needed after a Diag Reset if the FW has not
+ * changed.
+ */
+ if (attaching || reallocating) {
+ /*
+ * Check if controller supports FW diag buffers and set flag to
+ * enable each type.
+ */
+ if (sc->facts->IOCCapabilities &
+ MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER)
+ sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_TRACE].
+ enabled = TRUE;
+ if (sc->facts->IOCCapabilities &
+ MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
+ sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT].
+ enabled = TRUE;
+ if (sc->facts->IOCCapabilities &
+ MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
+ sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED].
+ enabled = TRUE;
+
+ /*
+ * Set flag if EEDP is supported and if TLR is supported.
+ */
+ if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP)
+ sc->eedp_enabled = TRUE;
+ if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)
+ sc->control_TLR = TRUE;
+
+ /*
+ * Size the queues. Since the reply queues always need one free
+ * entry, we'll just deduct one reply message here.
+ */
+ sc->num_reqs = MIN(MPS_REQ_FRAMES, sc->facts->RequestCredit);
+ sc->num_replies = MIN(MPS_REPLY_FRAMES + MPS_EVT_REPLY_FRAMES,
+ sc->facts->MaxReplyDescriptorPostQueueDepth) - 1;
+
+ /*
+ * Initialize all Tail Queues
+ */
+ TAILQ_INIT(&sc->req_list);
+ TAILQ_INIT(&sc->high_priority_req_list);
+ TAILQ_INIT(&sc->chain_list);
+ TAILQ_INIT(&sc->tm_list);
+ }
+
+ /*
+ * If doing a Diag Reset and the FW is significantly different
+ * (reallocating will be set above in IOC Facts comparison), then all
+ * buffers based on the IOC Facts will need to be freed before they are
+ * reallocated.
+ */
+ if (reallocating) {
+ mps_iocfacts_free(sc);
+
+ /*
+ * The number of targets is based on IOC Facts, so free all of
+ * the allocated LUNs for each target and then the target buffer
+ * itself.
+ */
+ for (i=0; i< saved_facts.MaxTargets; i++) {
+ targ = &sc->sassc->targets[i];
+ SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link,
+ lun_tmp) {
+ free(lun, M_MPT2);
+ }
+ }
+ free(sc->sassc->targets, M_MPT2);
+
+ sc->sassc->targets = malloc(sizeof(struct mpssas_target) *
+ sc->facts->MaxTargets, M_MPT2, M_WAITOK|M_ZERO);
+ if (!sc->sassc->targets) {
+ panic("%s failed to alloc targets with error %d\n",
+ __func__, ENOMEM);
+ }
+ }
+
+ /*
+ * Any deallocation has been completed. Now start reallocating
+ * if needed. Will only need to reallocate if attaching or if the new
+ * IOC Facts are different from the previous IOC Facts after a Diag
+ * Reset. Targets have already been allocated above if needed.
+ */
+ if (attaching || reallocating) {
+ if (((error = mps_alloc_queues(sc)) != 0) ||
+ ((error = mps_alloc_replies(sc)) != 0) ||
+ ((error = mps_alloc_requests(sc)) != 0)) {
+ if (attaching ) {
+ mps_dprint(sc, MPS_FAULT, "%s failed to alloc "
+ "queues with error %d\n", __func__, error);
+ mps_free(sc);
+ return (error);
+ } else {
+ panic("%s failed to alloc queues with error "
+ "%d\n", __func__, error);
+ }
+ }
+ }
+
+ /* Always initialize the queues */
+ bzero(sc->free_queue, sc->fqdepth * 4);
+ mps_init_queues(sc);
+
+ /*
+ * Always get the chip out of the reset state, but only panic if not
+ * attaching. If attaching and there is an error, that is handled by
+ * the OS.
+ */
+ error = mps_transition_operational(sc);
+ if (error != 0) {
+ if (attaching) {
+ mps_printf(sc, "%s failed to transition to operational "
+ "with error %d\n", __func__, error);
+ mps_free(sc);
+ return (error);
+ } else {
+ panic("%s failed to transition to operational with "
+ "error %d\n", __func__, error);
+ }
+ }
+
+ /*
+ * Finish the queue initialization.
+ * These are set here instead of in mps_init_queues() because the
+ * IOC resets these values during the state transition in
+ * mps_transition_operational(). The free index is set to 1
+ * because the corresponding index in the IOC is set to 0, and the
+ * IOC treats the queues as full if both are set to the same value.
+ * Hence the reason that the queue can't hold all of the possible
+ * replies.
+ */
+ sc->replypostindex = 0;
+ mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex);
+ mps_regwrite(sc, MPI2_REPLY_POST_HOST_INDEX_OFFSET, 0);
+
+ /*
+ * Attach the subsystems so they can prepare their event masks.
+ */
+ /* XXX Should be dynamic so that IM/IR and user modules can attach */
+ if (attaching) {
+ if (((error = mps_attach_log(sc)) != 0) ||
+ ((error = mps_attach_sas(sc)) != 0) ||
+ ((error = mps_attach_user(sc)) != 0)) {
+ mps_printf(sc, "%s failed to attach all subsystems: "
+ "error %d\n", __func__, error);
+ mps_free(sc);
+ return (error);
+ }
+
+ if ((error = mps_pci_setup_interrupts(sc)) != 0) {
+ mps_printf(sc, "%s failed to setup interrupts\n",
+ __func__);
+ mps_free(sc);
+ return (error);
+ }
+ }
+
+ /*
+ * Set flag if this is a WD controller. This shouldn't ever change, but
+ * reset it after a Diag Reset, just in case.
+ */
+ sc->WD_available = FALSE;
+ if (pci_get_device(sc->mps_dev) == MPI2_MFGPAGE_DEVID_SSS6200)
+ sc->WD_available = TRUE;
+
+ return (error);
+ }
+
+ /*
+ * This is called if memory is being free (during detach for example) and when
+ * buffers need to be reallocated due to a Diag Reset.
+ */
+ static void
+ mps_iocfacts_free(struct mps_softc *sc)
+ {
+ struct mps_command *cm;
+ int i;
+
+ mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
+
+ if (sc->post_busaddr != 0)
+ bus_dmamap_unload(sc->queues_dmat, sc->queues_map);
+ if (sc->post_queue != NULL)
+ bus_dmamem_free(sc->queues_dmat, sc->post_queue,
+ sc->queues_map);
+ if (sc->queues_dmat != NULL)
+ bus_dma_tag_destroy(sc->queues_dmat);
+
+ if (sc->chain_busaddr != 0)
+ bus_dmamap_unload(sc->chain_dmat, sc->chain_map);
+ if (sc->chain_frames != NULL)
+ bus_dmamem_free(sc->chain_dmat, sc->chain_frames,
+ sc->chain_map);
+ if (sc->chain_dmat != NULL)
+ bus_dma_tag_destroy(sc->chain_dmat);
+
+ if (sc->sense_busaddr != 0)
+ bus_dmamap_unload(sc->sense_dmat, sc->sense_map);
+ if (sc->sense_frames != NULL)
+ bus_dmamem_free(sc->sense_dmat, sc->sense_frames,
+ sc->sense_map);
+ if (sc->sense_dmat != NULL)
+ bus_dma_tag_destroy(sc->sense_dmat);
+
+ if (sc->reply_busaddr != 0)
+ bus_dmamap_unload(sc->reply_dmat, sc->reply_map);
+ if (sc->reply_frames != NULL)
+ bus_dmamem_free(sc->reply_dmat, sc->reply_frames,
+ sc->reply_map);
+ if (sc->reply_dmat != NULL)
+ bus_dma_tag_destroy(sc->reply_dmat);
+
+ if (sc->req_busaddr != 0)
+ bus_dmamap_unload(sc->req_dmat, sc->req_map);
+ if (sc->req_frames != NULL)
+ bus_dmamem_free(sc->req_dmat, sc->req_frames, sc->req_map);
+ if (sc->req_dmat != NULL)
+ bus_dma_tag_destroy(sc->req_dmat);
+
+ if (sc->chains != NULL)
+ free(sc->chains, M_MPT2);
+ if (sc->commands != NULL) {
+ for (i = 1; i < sc->num_reqs; i++) {
+ cm = &sc->commands[i];
+ bus_dmamap_destroy(sc->buffer_dmat, cm->cm_dmamap);
+ }
+ free(sc->commands, M_MPT2);
+ }
+ if (sc->buffer_dmat != NULL)
+ bus_dma_tag_destroy(sc->buffer_dmat);
+ }
+
/*
* The terms diag reset and hard reset are used interchangeably in the MPI
* docs to mean resetting the controller chip. In this code diag reset
* cleans everything up, and the hard reset function just sends the reset
***************
*** 316,322 ****
mps_reinit(struct mps_softc *sc)
{
int error;
- uint32_t db;
mps_printf(sc, "%s sc %p\n", __func__, sc);
--- 675,680 ----
***************
*** 332,344 ****
*/
sc->mps_flags |= MPS_FLAGS_DIAGRESET;
mps_printf(sc, "%s mask interrupts\n", __func__);
mps_mask_intr(sc);
error = mps_diag_reset(sc, CAN_SLEEP);
if (error != 0) {
! panic("%s hard reset failed with error %d\n",
! __func__, error);
}
/* Restore the PCI state, including the MSI-X registers */
--- 690,704 ----
*/
sc->mps_flags |= MPS_FLAGS_DIAGRESET;
+ /*
+ * Mask interrupts here.
+ */
mps_printf(sc, "%s mask interrupts\n", __func__);
mps_mask_intr(sc);
error = mps_diag_reset(sc, CAN_SLEEP);
if (error != 0) {
! panic("%s hard reset failed with error %d\n", __func__, error);
}
/* Restore the PCI state, including the MSI-X registers */
***************
*** 347,395 ****
/* Give the I/O subsystem special priority to get itself prepared */
mpssas_handle_reinit(sc);
! /* reinitialize queues after the reset */
! bzero(sc->free_queue, sc->fqdepth * 4);
! mps_init_queues(sc);
!
! /* get the chip out of the reset state */
! error = mps_transition_operational(sc);
! if (error != 0)
! panic("%s transition operational failed with error %d\n",
__func__, error);
! /* Reinitialize the reply queue. This is delicate because this
! * function is typically invoked by task mgmt completion callbacks,
! * which are called by the interrupt thread. We need to make sure
! * the interrupt handler loop will exit when we return to it, and
! * that it will recognize the indexes we've changed.
*/
! sc->replypostindex = 0;
! mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex);
! mps_regwrite(sc, MPI2_REPLY_POST_HOST_INDEX_OFFSET, sc->replypostindex);
! db = mps_regread(sc, MPI2_DOORBELL_OFFSET);
! mps_printf(sc, "%s doorbell 0x%08x\n", __func__, db);
!
! mps_printf(sc, "%s unmask interrupts post %u free %u\n", __func__,
! sc->replypostindex, sc->replyfreeindex);
!
mps_unmask_intr(sc);
! mps_printf(sc, "%s restarting post %u free %u\n", __func__,
! sc->replypostindex, sc->replyfreeindex);
! /* restart will reload the event masks clobbered by the reset, and
* then enable the port.
*/
mps_reregister_events(sc);
/* the end of discovery will release the simq, so we're done. */
! mps_printf(sc, "%s finished sc %p post %u free %u\n",
! __func__, sc,
sc->replypostindex, sc->replyfreeindex);
- sc->mps_flags &= ~MPS_FLAGS_DIAGRESET;
-
return 0;
}
--- 707,756 ----
/* Give the I/O subsystem special priority to get itself prepared */
mpssas_handle_reinit(sc);
! /*
! * Get IOC Facts and allocate all structures based on this information.
! * The attach function will also call mps_iocfacts_allocate at startup.
! * If relevant values have changed in IOC Facts, this function will free
! * all of the memory based on IOC Facts and reallocate that memory.
! */
! if ((error = mps_iocfacts_allocate(sc, FALSE)) != 0) {
! panic("%s IOC Facts based allocation failed with error %d\n",
__func__, error);
+ }
! /*
! * Mapping structures will be re-allocated after getting IOC Page8, so
! * free these structures here.
*/
! mps_mapping_exit(sc);
! /*
! * The static page function currently read is IOC Page8. Others can be
! * added in future. It's possible that the values in IOC Page8 have
! * changed after a Diag Reset due to user modification, so always read
! * these. Interrupts are masked, so unmask them before getting config
! * pages.
! */
mps_unmask_intr(sc);
+ sc->mps_flags &= ~MPS_FLAGS_DIAGRESET;
+ mps_base_static_config_pages(sc);
! /*
! * Some mapping info is based in IOC Page8 data, so re-initialize the
! * mapping tables.
! */
! mps_mapping_initialize(sc);
! /*
! * Restart will reload the event masks clobbered by the reset, and
* then enable the port.
*/
mps_reregister_events(sc);
/* the end of discovery will release the simq, so we're done. */
! mps_printf(sc, "%s finished sc %p post %u free %u\n", __func__, sc,
sc->replypostindex, sc->replyfreeindex);
return 0;
}
***************
*** 634,681 ****
}
static int
- mps_get_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts, int port)
- {
- MPI2_PORT_FACTS_REQUEST *request;
- MPI2_PORT_FACTS_REPLY *reply;
- struct mps_command *cm;
- int error;
-
- mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
-
- if ((cm = mps_alloc_command(sc)) == NULL)
- return (EBUSY);
- request = (MPI2_PORT_FACTS_REQUEST *)cm->cm_req;
- request->Function = MPI2_FUNCTION_PORT_FACTS;
- request->PortNumber = port;
- cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
- cm->cm_data = NULL;
- error = mps_request_polled(sc, cm);
- reply = (MPI2_PORT_FACTS_REPLY *)cm->cm_reply;
- if (reply == NULL) {
- mps_printf(sc, "%s NULL reply\n", __func__);
- goto done;
- }
- if ((reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) {
- mps_printf(sc,
- "%s error %d iocstatus 0x%x iocloginfo 0x%x type 0x%x\n",
- __func__, error, reply->IOCStatus, reply->IOCLogInfo,
- reply->PortType);
- error = ENXIO;
- }
- bcopy(reply, facts, sizeof(MPI2_PORT_FACTS_REPLY));
- done:
- mps_free_command(sc, cm);
-
- return (error);
- }
-
- static int
mps_send_iocinit(struct mps_softc *sc)
{
MPI2_IOC_INIT_REQUEST init;
MPI2_DEFAULT_REPLY reply;
int req_sz, reply_sz, error;
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
--- 995,1007 ----
}
static int
mps_send_iocinit(struct mps_softc *sc)
{
MPI2_IOC_INIT_REQUEST init;
MPI2_DEFAULT_REPLY reply;
int req_sz, reply_sz, error;
+ struct timeval now;
+ uint64_t time_in_msec;
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
***************
*** 704,711 ****
init.ReplyDescriptorPostQueueAddress.Low = htole32((uint32_t)sc->post_busaddr);
init.ReplyFreeQueueAddress.High = 0;
init.ReplyFreeQueueAddress.Low = htole32((uint32_t)sc->free_busaddr);
! init.TimeStamp.High = 0;
! init.TimeStamp.Low = htole32((uint32_t)time_uptime);
error = mps_request_sync(sc, &init, &reply, req_sz, reply_sz, 5);
if ((reply.IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
--- 1030,1039 ----
init.ReplyDescriptorPostQueueAddress.Low = htole32((uint32_t)sc->post_busaddr);
init.ReplyFreeQueueAddress.High = 0;
init.ReplyFreeQueueAddress.Low = htole32((uint32_t)sc->free_busaddr);
! getmicrotime(&now);
! time_in_msec = (now.tv_sec * 1000 + now.tv_usec/1000);
! init.TimeStamp.High = htole32((time_in_msec >> 32) & 0xFFFFFFFF);
! init.TimeStamp.Low = htole32(time_in_msec & 0xFFFFFFFF);
error = mps_request_sync(sc, &init, &reply, req_sz, reply_sz, 5);
if ((reply.IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
***************
*** 1119,1125 ****
int
mps_attach(struct mps_softc *sc)
{
! int i, error;
mps_get_tunables(sc);
--- 1447,1453 ----
int
mps_attach(struct mps_softc *sc)
{
! int error;
mps_get_tunables(sc);
***************
*** 1141,1291 ****
__func__, __LINE__);
return (ENOMEM);
}
- if ((error = mps_get_iocfacts(sc, sc->facts)) != 0)
- return (error);
-
- mps_print_iocfacts(sc, sc->facts);
-
- snprintf(sc->fw_version, sizeof(sc->fw_version),
- "%02d.%02d.%02d.%02d",
- sc->facts->FWVersion.Struct.Major,
- sc->facts->FWVersion.Struct.Minor,
- sc->facts->FWVersion.Struct.Unit,
- sc->facts->FWVersion.Struct.Dev);
- mps_printf(sc, "Firmware: %s, Driver: %s\n", sc->fw_version,
- MPS_DRIVER_VERSION);
- mps_printf(sc, "IOCCapabilities: %b\n", sc->facts->IOCCapabilities,
- "\20" "\3ScsiTaskFull" "\4DiagTrace" "\5SnapBuf" "\6ExtBuf"
- "\7EEDP" "\10BiDirTarg" "\11Multicast" "\14TransRetry" "\15IR"
- "\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc");
-
/*
! * If the chip doesn't support event replay then a hard reset will be
! * required to trigger a full discovery. Do the reset here then
! * retransition to Ready. A hard reset might have already been done,
! * but it doesn't hurt to do it again.
*/
! if ((sc->facts->IOCCapabilities &
! MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) == 0) {
! mps_diag_reset(sc, NO_SLEEP);
! if ((error = mps_transition_ready(sc)) != 0)
! return (error);
! }
!
! /*
! * Set flag if IR Firmware is loaded.
! */
! if (sc->facts->IOCCapabilities &
! MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)
! sc->ir_firmware = 1;
!
! /*
! * Check if controller supports FW diag buffers and set flag to enable
! * each type.
! */
! if (sc->facts->IOCCapabilities &
! MPI2_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER)
! sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_TRACE].enabled =
! TRUE;
! if (sc->facts->IOCCapabilities &
! MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
! sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_SNAPSHOT].enabled =
! TRUE;
! if (sc->facts->IOCCapabilities &
! MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
! sc->fw_diag_buffer_list[MPI2_DIAG_BUF_TYPE_EXTENDED].enabled =
! TRUE;
!
! /*
! * Set flag if EEDP is supported and if TLR is supported.
! */
! if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_EEDP)
! sc->eedp_enabled = TRUE;
! if (sc->facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)
! sc->control_TLR = TRUE;
!
! /*
! * Size the queues. Since the reply queues always need one free entry,
! * we'll just deduct one reply message here.
! */
! sc->num_reqs = MIN(MPS_REQ_FRAMES, sc->facts->RequestCredit);
! sc->num_replies = MIN(MPS_REPLY_FRAMES + MPS_EVT_REPLY_FRAMES,
! sc->facts->MaxReplyDescriptorPostQueueDepth) - 1;
! TAILQ_INIT(&sc->req_list);
! TAILQ_INIT(&sc->high_priority_req_list);
! TAILQ_INIT(&sc->chain_list);
! TAILQ_INIT(&sc->tm_list);
!
! if (((error = mps_alloc_queues(sc)) != 0) ||
! ((error = mps_alloc_replies(sc)) != 0) ||
! ((error = mps_alloc_requests(sc)) != 0)) {
! mps_printf(sc, "%s failed to alloc\n", __func__);
! mps_free(sc);
! return (error);
! }
!
! if (((error = mps_init_queues(sc)) != 0) ||
! ((error = mps_transition_operational(sc)) != 0)) {
! mps_printf(sc, "%s failed to transition operational\n", __func__);
! mps_free(sc);
! return (error);
! }
!
! /*
! * Finish the queue initialization.
! * These are set here instead of in mps_init_queues() because the
! * IOC resets these values during the state transition in
! * mps_transition_operational(). The free index is set to 1
! * because the corresponding index in the IOC is set to 0, and the
! * IOC treats the queues as full if both are set to the same value.
! * Hence the reason that the queue can't hold all of the possible
! * replies.
! */
! sc->replypostindex = 0;
! mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex);
! mps_regwrite(sc, MPI2_REPLY_POST_HOST_INDEX_OFFSET, 0);
!
! sc->pfacts = malloc(sizeof(MPI2_PORT_FACTS_REPLY) *
! sc->facts->NumberOfPorts, M_MPT2, M_ZERO|M_WAITOK);
! if(!sc->pfacts) {
! device_printf(sc->mps_dev, "Cannot allocate memory %s %d\n",
! __func__, __LINE__);
! return (ENOMEM);
! }
! for (i = 0; i < sc->facts->NumberOfPorts; i++) {
! if ((error = mps_get_portfacts(sc, &sc->pfacts[i], i)) != 0) {
! mps_printf(sc, "%s failed to get portfacts for port %d\n",
! __func__, i);
! mps_free(sc);
! return (error);
! }
! mps_print_portfacts(sc, &sc->pfacts[i]);
! }
!
! /* Attach the subsystems so they can prepare their event masks. */
! /* XXX Should be dynamic so that IM/IR and user modules can attach */
! if (((error = mps_attach_log(sc)) != 0) ||
! ((error = mps_attach_sas(sc)) != 0) ||
! ((error = mps_attach_user(sc)) != 0)) {
! mps_printf(sc, "%s failed to attach all subsystems: error %d\n",
! __func__, error);
! mps_free(sc);
! return (error);
! }
!
! if ((error = mps_pci_setup_interrupts(sc)) != 0) {
! mps_printf(sc, "%s failed to setup interrupts\n", __func__);
! mps_free(sc);
return (error);
}
- /*
- * The static page function currently read is ioc page8. Others can be
- * added in future.
- */
- mps_base_static_config_pages(sc);
-
/* Start the periodic watchdog check on the IOC Doorbell */
mps_periodic(sc);
--- 1469,1488 ----
__func__, __LINE__);
return (ENOMEM);
}
/*
! * Get IOC Facts and allocate all structures based on this information.
! * A Diag Reset will also call mps_iocfacts_allocate and re-read the IOC
! * Facts. If relevant values have changed in IOC Facts, this function
! * will free all of the memory based on IOC Facts and reallocate that
! * memory. If this fails, any allocated memory should already be freed.
*/
! if ((error = mps_iocfacts_allocate(sc, TRUE)) != 0) {
! mps_dprint(sc, MPS_FAULT, "%s IOC Facts based allocation "
! "failed with error %d\n", __func__, error);
return (error);
}
/* Start the periodic watchdog check on the IOC Doorbell */
mps_periodic(sc);
***************
*** 1328,1334 ****
--- 1525,1533 ----
mps_lock(sc);
mps_unmask_intr(sc);
+
/* initialize device mapping tables */
+ mps_base_static_config_pages(sc);
mps_mapping_initialize(sc);
mpssas_startup(sc);
mps_unlock(sc);
***************
*** 1411,1418 ****
int
mps_free(struct mps_softc *sc)
{
! struct mps_command *cm;
! int i, error;
/* Turn off the watchdog */
mps_lock(sc);
--- 1610,1616 ----
int
mps_free(struct mps_softc *sc)
{
! int error;
/* Turn off the watchdog */
mps_lock(sc);
***************
*** 1438,1499 ****
if (sc->facts != NULL)
free(sc->facts, M_MPT2);
! if (sc->pfacts != NULL)
! free(sc->pfacts, M_MPT2);
!
! if (sc->post_busaddr != 0)
! bus_dmamap_unload(sc->queues_dmat, sc->queues_map);
! if (sc->post_queue != NULL)
! bus_dmamem_free(sc->queues_dmat, sc->post_queue,
! sc->queues_map);
! if (sc->queues_dmat != NULL)
! bus_dma_tag_destroy(sc->queues_dmat);
!
! if (sc->chain_busaddr != 0)
! bus_dmamap_unload(sc->chain_dmat, sc->chain_map);
! if (sc->chain_frames != NULL)
! bus_dmamem_free(sc->chain_dmat, sc->chain_frames,sc->chain_map);
! if (sc->chain_dmat != NULL)
! bus_dma_tag_destroy(sc->chain_dmat);
!
! if (sc->sense_busaddr != 0)
! bus_dmamap_unload(sc->sense_dmat, sc->sense_map);
! if (sc->sense_frames != NULL)
! bus_dmamem_free(sc->sense_dmat, sc->sense_frames,sc->sense_map);
! if (sc->sense_dmat != NULL)
! bus_dma_tag_destroy(sc->sense_dmat);
!
! if (sc->reply_busaddr != 0)
! bus_dmamap_unload(sc->reply_dmat, sc->reply_map);
! if (sc->reply_frames != NULL)
! bus_dmamem_free(sc->reply_dmat, sc->reply_frames,sc->reply_map);
! if (sc->reply_dmat != NULL)
! bus_dma_tag_destroy(sc->reply_dmat);
!
! if (sc->req_busaddr != 0)
! bus_dmamap_unload(sc->req_dmat, sc->req_map);
! if (sc->req_frames != NULL)
! bus_dmamem_free(sc->req_dmat, sc->req_frames, sc->req_map);
! if (sc->req_dmat != NULL)
! bus_dma_tag_destroy(sc->req_dmat);
- if (sc->chains != NULL)
- free(sc->chains, M_MPT2);
- if (sc->commands != NULL) {
- for (i = 1; i < sc->num_reqs; i++) {
- cm = &sc->commands[i];
- bus_dmamap_destroy(sc->buffer_dmat, cm->cm_dmamap);
- }
- free(sc->commands, M_MPT2);
- }
- if (sc->buffer_dmat != NULL)
- bus_dma_tag_destroy(sc->buffer_dmat);
-
if (sc->sysctl_tree != NULL)
sysctl_ctx_free(&sc->sysctl_ctx);
- mps_mapping_free_memory(sc);
-
/* Deregister the shutdown function */
if (sc->shutdown_eh != NULL)
EVENTHANDLER_DEREGISTER(shutdown_final, sc->shutdown_eh);
--- 1636,1650 ----
if (sc->facts != NULL)
free(sc->facts, M_MPT2);
! /*
! * Free all buffers that are based on IOC Facts. A Diag Reset may need
! * to free these buffers too.
! */
! mps_iocfacts_free(sc);
if (sc->sysctl_tree != NULL)
sysctl_ctx_free(&sc->sysctl_ctx);
/* Deregister the shutdown function */
if (sc->shutdown_eh != NULL)
EVENTHANDLER_DEREGISTER(shutdown_final, sc->shutdown_eh);
***************
*** 1914,1920 ****
/* first, reregister events */
! for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
sc->event_mask[i] = -1;
TAILQ_FOREACH(eh, &sc->event_list, eh_list) {
--- 2065,2071 ----
/* first, reregister events */
! for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
sc->event_mask[i] = -1;
TAILQ_FOREACH(eh, &sc->event_list, eh_list) {
***************
*** 1946,1952 ****
error = mps_map_command(sc, cm);
! mps_dprint(sc, MPS_TRACE, "%s finished with error %d\n", __func__, error);
return (error);
}
--- 2097,2104 ----
error = mps_map_command(sc, cm);
! mps_dprint(sc, MPS_TRACE, "%s finished with error %d\n", __func__,
! error);
return (error);
}
***************
*** 2325,2350 ****
* be executed and enqueued automatically. Other errors come from msleep().
*/
int
! mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout)
{
int error, rc;
! mtx_assert(&sc->mps_mtx, MA_OWNED);
!
! if(sc->mps_flags & MPS_FLAGS_DIAGRESET)
return EBUSY;
cm->cm_complete = NULL;
! cm->cm_flags |= MPS_CM_FLAGS_WAKEUP;
error = mps_map_command(sc, cm);
if ((error != 0) && (error != EINPROGRESS))
return (error);
! error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout*hz);
if (error == EWOULDBLOCK) {
mps_dprint(sc, MPS_FAULT, "Calling Reinit from %s\n", __func__);
rc = mps_reinit(sc);
! mps_dprint(sc, MPS_FAULT, "Reinit %s\n",
! (rc == 0) ? "success" : "failed");
error = ETIMEDOUT;
}
return (error);
--- 2477,2526 ----
* be executed and enqueued automatically. Other errors come from msleep().
*/
int
! mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
! int sleep_flag)
{
int error, rc;
+ struct timeval cur_time, start_time;
! if (sc->mps_flags & MPS_FLAGS_DIAGRESET)
return EBUSY;
cm->cm_complete = NULL;
! cm->cm_flags |= (MPS_CM_FLAGS_WAKEUP + MPS_CM_FLAGS_POLLED);
error = mps_map_command(sc, cm);
if ((error != 0) && (error != EINPROGRESS))
return (error);
!
! // Check for context and wait for 50 mSec at a time until time has
! // expired or the command has finished. If msleep can't be used, need
! // to poll.
! if (curthread->td_pflags & TDP_NOSLEEPING)
! sleep_flag = NO_SLEEP;
! getmicrotime(&start_time);
! if (mtx_owned(&sc->mps_mtx) && sleep_flag == CAN_SLEEP) {
! error = msleep(cm, &sc->mps_mtx, 0, "mpswait", timeout*hz);
! } else {
! while ((cm->cm_flags & MPS_CM_FLAGS_COMPLETE) == 0) {
! mps_intr_locked(sc);
! if (sleep_flag == CAN_SLEEP)
! pause("mpswait", hz/20);
! else
! DELAY(50000);
!
! getmicrotime(&cur_time);
! if ((cur_time.tv_sec - start_time.tv_sec) > timeout) {
! error = EWOULDBLOCK;
! break;
! }
! }
! }
!
if (error == EWOULDBLOCK) {
mps_dprint(sc, MPS_FAULT, "Calling Reinit from %s\n", __func__);
rc = mps_reinit(sc);
! mps_dprint(sc, MPS_FAULT, "Reinit %s\n", (rc == 0) ? "success" :
! "failed");
error = ETIMEDOUT;
}
return (error);
***************
*** 2444,2450 ****
cm->cm_complete = mps_config_complete;
return (mps_map_command(sc, cm));
} else {
! error = mps_wait_command(sc, cm, 0);
if (error) {
mps_dprint(sc, MPS_FAULT,
"Error %d reading config page\n", error);
--- 2620,2626 ----
cm->cm_complete = mps_config_complete;
return (mps_map_command(sc, cm));
} else {
! error = mps_wait_command(sc, cm, 0, CAN_SLEEP);
if (error) {
mps_dprint(sc, MPS_FAULT,
"Error %d reading config page\n", error);
*** src/sys/dev/mps/mps_config.c.orig
--- src/sys/dev/mps/mps_config.c
***************
*** 93,104 ****
request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 93,107 ----
request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 107,113 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 110,119 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 144,155 ****
goto out;
}
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 150,165 ----
goto out;
}
cm->cm_data = page;
!
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 158,164 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 168,177 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 211,216 ****
--- 224,234 ----
request->Header.PageVersion = MPI2_MANUFACTURING10_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
+
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
***************
*** 262,267 ****
--- 280,290 ----
goto out;
}
cm->cm_data = page;
+
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
***************
*** 561,572 ****
MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 584,598 ----
MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 575,581 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 601,610 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 615,626 ****
goto out;
}
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 644,658 ----
goto out;
}
cm->cm_data = page;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 629,635 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 661,670 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 685,696 ****
request->PageAddress |= htole16(entry_idx);
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 720,734 ----
request->PageAddress |= htole16(entry_idx);
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 699,705 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 737,746 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 741,752 ****
bcopy(config_page, page, MIN(cm->cm_length,
(sizeof(Mpi2DriverMappingPage0_t))));
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 782,796 ----
bcopy(config_page, page, MIN(cm->cm_length,
(sizeof(Mpi2DriverMappingPage0_t))));
cm->cm_data = page;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request to write page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 755,761 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page written with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 799,808 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page written with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 808,819 ****
request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 855,869 ----
request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 822,828 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 872,881 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 862,873 ****
}
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 915,929 ----
}
cm->cm_data = page;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 876,882 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 932,941 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 928,939 ****
request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 987,1001 ----
request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 942,948 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 1004,1013 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 980,991 ****
}
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 1045,1059 ----
}
cm->cm_data = page;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 994,1000 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 1062,1071 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 1046,1051 ****
--- 1117,1127 ----
request->Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
+
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
***************
*** 1099,1104 ****
--- 1175,1184 ----
}
cm->cm_data = page;
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
***************
*** 1166,1177 ****
request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 1246,1260 ----
request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for header completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 1180,1186 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 1263,1272 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: header read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 1219,1230 ****
}
cm->cm_data = page;
! error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 1305,1319 ----
}
cm->cm_data = page;
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 1233,1239 ****
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
--- 1322,1331 ----
bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY));
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
printf("%s: page read with error; iocstatus = 0x%x\n",
__func__, ioc_status);
error = ENXIO;
***************
*** 1311,1316 ****
--- 1403,1413 ----
request->Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = NULL;
+
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
***************
*** 1364,1369 ****
--- 1461,1470 ----
}
cm->cm_data = page;
+ /*
+ * This page must be polled because the IOC isn't ready yet when this
+ * page is needed.
+ */
error = mps_request_polled(sc, cm);
reply = (MPI2_CONFIG_REPLY *)cm->cm_reply;
if (error || (reply == NULL)) {
*** src/sys/dev/mps/mps_mapping.c.orig
--- src/sys/dev/mps/mps_mapping.c
***************
*** 1216,1227 ****
phy_change->is_processed = 1;
} else {
phy_change->is_processed = 1;
! printf("%s: failed to add the "
! "device with handle 0x%04x "
! "to persistent table "
! "because there is no free "
! "space available\n",
! __func__,
phy_change->dev_handle);
}
} else {
--- 1216,1227 ----
phy_change->is_processed = 1;
} else {
phy_change->is_processed = 1;
! mps_dprint(sc, MPS_INFO, "%s: "
! "failed to add the device "
! "with handle 0x%04x to "
! "persistent table because "
! "there is no free space "
! "available\n", __func__,
phy_change->dev_handle);
}
} else {
***************
*** 1318,1329 ****
phy_change->is_processed = 1;
} else if (dpm_idx == MPS_DPM_BAD_IDX) {
phy_change->is_processed = 1;
! printf("%s: failed to add the "
! "device with handle 0x%04x "
! "to persistent table "
! "because there is no free "
! "space available\n",
! __func__,
phy_change->dev_handle);
}
}
--- 1318,1329 ----
phy_change->is_processed = 1;
} else if (dpm_idx == MPS_DPM_BAD_IDX) {
phy_change->is_processed = 1;
! mps_dprint(sc, MPS_INFO, "%s: "
! "failed to add the device "
! "with handle 0x%04x to "
! "persistent table because "
! "there is no free space "
! "available\n", __func__,
phy_change->dev_handle);
}
}
*** src/sys/dev/mps/mps_sas.c.orig
--- src/sys/dev/mps/mps_sas.c
***************
*** 136,149 ****
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);
static void mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb);
#endif
static int mpssas_send_portenable(struct mps_softc *sc);
--- 136,147 ----
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_async(void *callback_arg, uint32_t code,
struct cam_path *path, void *arg);
! #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);
***************
*** 198,205 ****
--- 196,208 ----
mps_dprint(sassc->sc, MPS_INFO,
"%s releasing simq\n", __func__);
sassc->flags &= ~MPSSAS_IN_STARTUP;
+ #if (__FreeBSD_version >= 1000036) || \
+ ((__FreeBSD_version < 1000000) && (__FreeBSD_version >= 9010506))
+ xpt_release_boot();
+ #else
xpt_release_simq(sassc->sim, 1);
mpssas_rescan_target(sassc->sc, NULL);
+ #endif
}
mps_dprint(sassc->sc, MPS_TRACE, "%s refcount %u\n", __func__,
sassc->startup_refcount);
***************
*** 247,253 ****
mps_free_high_priority_command(sc, tm);
}
-
void
mpssas_rescan_target(struct mps_softc *sc, struct mpssas_target *targ)
{
--- 250,255 ----
***************
*** 272,278 ****
}
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid,
! targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
mps_dprint(sc, MPS_FAULT, "unable to create path for rescan\n");
xpt_free_ccb(ccb);
return;
--- 274,280 ----
}
if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid,
! targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
mps_dprint(sc, MPS_FAULT, "unable to create path for rescan\n");
xpt_free_ccb(ccb);
return;
***************
*** 284,290 ****
ccb->ccb_h.func_code = XPT_SCAN_TGT;
mps_dprint(sc, MPS_TRACE, "%s targetid %u\n", __func__, targetid);
! mpssas_rescan(sassc, ccb);
}
static void
--- 286,292 ----
ccb->ccb_h.func_code = XPT_SCAN_TGT;
mps_dprint(sc, MPS_TRACE, "%s targetid %u\n", __func__, targetid);
! xpt_rescan(ccb);
}
static void
***************
*** 671,679 ****
mps_attach_sas(struct mps_softc *sc)
{
struct mpssas_softc *sassc;
- #if __FreeBSD_version >= 1000006
cam_status status;
- #endif
int unit, error = 0;
mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
--- 673,679 ----
***************
*** 721,736 ****
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
--- 721,727 ----
***************
*** 745,756 ****
}
/*
! * Assume that discovery events will start right away. Freezing
! * the simq will prevent the CAM boottime scanner from running
! * before discovery is complete.
*/
sassc->flags |= MPSSAS_IN_STARTUP | MPSSAS_IN_DISCOVERY;
xpt_freeze_simq(sassc->sim, 1);
sc->sassc->startup_refcount = 0;
callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
--- 736,752 ----
}
/*
! * 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 >= 1000036) || \
+ ((__FreeBSD_version < 1000000) && (__FreeBSD_version >= 9010506))
+ xpt_hold_boot();
+ #else
xpt_freeze_simq(sassc->sim, 1);
+ #endif
sc->sassc->startup_refcount = 0;
callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
***************
*** 758,770 ****
sassc->tm_count = 0;
! #if __FreeBSD_version >= 1000006
! status = xpt_register_async(AC_ADVINFO_CHANGED, mpssas_async, sc, NULL);
if (status != CAM_REQ_CMP) {
! mps_printf(sc, "Error %#x registering async handler for "
! "AC_ADVINFO_CHANGED events\n", status);
}
- #endif
mps_unlock(sc);
--- 754,794 ----
sassc->tm_count = 0;
! /*
! * 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_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_printf(sc, "Error %#x registering async handler "
! "for event type 0x%x\n", status, event);
! 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);
***************
*** 803,811 ****
mps_lock(sc);
/* Deregister our async handler */
! #if __FreeBSD_version >= 1000006
! xpt_register_async(0, mpssas_async, sc, NULL);
! #endif
if (sassc->flags & MPSSAS_IN_STARTUP)
xpt_release_simq(sassc->sim, 1);
--- 827,837 ----
mps_lock(sc);
/* Deregister our async handler */
! 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);
***************
*** 815,829 ****
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);
! }
! }
mps_unlock(sc);
mps_dprint(sc, MPS_INFO, "%s:%d\n", __func__,__LINE__);
--- 841,847 ----
cam_sim_free(sassc->sim, FALSE);
}
! sassc->flags |= MPSSAS_SHUTDOWN;
mps_unlock(sc);
mps_dprint(sc, MPS_INFO, "%s:%d\n", __func__,__LINE__);
***************
*** 914,920 ****
--- 932,943 ----
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
cpi->target_sprt = 0;
+ #if (__FreeBSD_version >= 1000036) || \
+ ((__FreeBSD_version < 1000000) && (__FreeBSD_version >= 9010506))
+ 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;
***************
*** 1580,1586 ****
csio = &ccb->csio;
targ = &sassc->targets[csio->ccb_h.target_id];
! mps_dprint(sc, MPS_TRACE, "%s ccb %p target flag %x\n", __func__, ccb, targ->flags);
if (targ->handle == 0x0) {
mps_dprint(sc, MPS_TRACE, "%s NULL handle for target %u\n",
__func__, csio->ccb_h.target_id);
--- 1603,1610 ----
csio = &ccb->csio;
targ = &sassc->targets[csio->ccb_h.target_id];
! mps_dprint(sc, MPS_TRACE, "%s ccb %p target flag %x\n", __func__, ccb,
! targ->flags);
if (targ->handle == 0x0) {
mps_dprint(sc, MPS_TRACE, "%s NULL handle for target %u\n",
__func__, csio->ccb_h.target_id);
***************
*** 1589,1601 ****
return;
}
if (targ->flags & MPS_TARGET_FLAGS_RAID_COMPONENT) {
! mps_dprint(sc, MPS_TRACE, "%s Raid component no SCSI IO supported %u\n",
! __func__, csio->ccb_h.target_id);
csio->ccb_h.status = CAM_TID_INVALID;
xpt_done(ccb);
return;
}
/*
* If devinfo is 0 this will be a volume. In that case don't tell CAM
* that the volume has timed out. We want volumes to be enumerated
* until they are deleted/removed, not just failed.
--- 1613,1636 ----
return;
}
if (targ->flags & MPS_TARGET_FLAGS_RAID_COMPONENT) {
! mps_dprint(sc, MPS_TRACE, "%s Raid component no SCSI IO "
! "supported %u\n", __func__, csio->ccb_h.target_id);
csio->ccb_h.status = CAM_TID_INVALID;
xpt_done(ccb);
return;
}
/*
+ * Sometimes, it is possible to get a command that is not "In
+ * Progress" and was actually aborted by the upper layer. Check for
+ * this here and complete the command without error.
+ */
+ if (ccb->ccb_h.status != CAM_REQ_INPROG) {
+ mps_dprint(sc, MPS_TRACE, "%s Command is not in progress for "
+ "target %u\n", __func__, csio->ccb_h.target_id);
+ xpt_done(ccb);
+ return;
+ }
+ /*
* If devinfo is 0 this will be a volume. In that case don't tell CAM
* that the volume has timed out. We want volumes to be enumerated
* until they are deleted/removed, not just failed.
***************
*** 1663,1669 ****
break;
}
! if (csio->cdb_len == 32)
mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT;
/*
* It looks like the hardware doesn't require an explicit tag
--- 1698,1704 ----
break;
}
! if (csio->cdb_len == 32)
mpi_control |= 4 << MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT;
/*
* It looks like the hardware doesn't require an explicit tag
***************
*** 1791,1796 ****
--- 1826,1832 ----
targ->issued++;
targ->outstanding++;
TAILQ_INSERT_TAIL(&targ->commands, cm, cm_link);
+ ccb->ccb_h.status |= CAM_SIM_QUEUED;
if ((sc->mps_debug & MPS_TRACE) != 0)
mpssas_log_command(cm, "%s cm %p ccb %p outstanding %u\n",
***************
*** 1969,1982 ****
strcat(desc_scsi_state, "autosense valid ");
mps_dprint(sc, MPS_INFO, "\thandle(0x%04x), ioc_status(%s)(0x%04x), \n",
! le16toh(mpi_reply->DevHandle),
! desc_ioc_state, ioc_status);
/* We can add more detail about underflow data here
* TO-DO
* */
mps_dprint(sc, MPS_INFO, "\tscsi_status(%s)(0x%02x), "
! "scsi_state(%s)(0x%02x)\n", desc_scsi_status,
! scsi_status, desc_scsi_state, scsi_state);
if (sc->mps_debug & MPS_INFO &&
scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
--- 2005,2017 ----
strcat(desc_scsi_state, "autosense valid ");
mps_dprint(sc, MPS_INFO, "\thandle(0x%04x), ioc_status(%s)(0x%04x), \n",
! le16toh(mpi_reply->DevHandle), desc_ioc_state, ioc_status);
/* We can add more detail about underflow data here
* TO-DO
* */
mps_dprint(sc, MPS_INFO, "\tscsi_status(%s)(0x%02x), "
! "scsi_state(%s)(0x%02x)\n", desc_scsi_status, scsi_status,
! desc_scsi_state, scsi_state);
if (sc->mps_debug & MPS_INFO &&
scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
***************
*** 2033,2038 ****
--- 2068,2074 ----
cm->cm_targ->completed++;
cm->cm_targ->outstanding--;
TAILQ_REMOVE(&cm->cm_targ->commands, cm, cm_link);
+ ccb->ccb_h.status |= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED);
if (cm->cm_state == MPS_CM_STATE_TIMEDOUT) {
TAILQ_REMOVE(&cm->cm_targ->timedout_commands, cm, cm_recovery);
***************
*** 2108,2114 ****
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
mps_dprint(sc, MPS_INFO,
! "Unfreezing SIM queue\n");
}
}
--- 2144,2150 ----
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
mps_dprint(sc, MPS_INFO,
! "Unfreezing SIM queue\n");
}
}
***************
*** 2335,2341 ****
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
mps_dprint(sc, MPS_INFO, "Command completed, "
! "unfreezing SIM queue\n");
}
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
--- 2371,2377 ----
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
mps_dprint(sc, MPS_INFO, "Command completed, "
! "unfreezing SIM queue\n");
}
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
***************
*** 2651,2657 ****
sasaddr = le32toh(req->SASAddress.Low);
sasaddr |= ((uint64_t)(le32toh(req->SASAddress.High))) << 32;
! if ((le16toh(rpl->IOCStatus) & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS ||
rpl->SASStatus != MPI2_SASSTATUS_SUCCESS) {
mps_dprint(sc, MPS_INFO, "%s: IOCStatus %04x SASStatus %02x\n",
__func__, le16toh(rpl->IOCStatus), rpl->SASStatus);
--- 2687,2694 ----
sasaddr = le32toh(req->SASAddress.Low);
sasaddr |= ((uint64_t)(le32toh(req->SASAddress.High))) << 32;
! if ((le16toh(rpl->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
! MPI2_IOCSTATUS_SUCCESS ||
rpl->SASStatus != MPI2_SASSTATUS_SUCCESS) {
mps_dprint(sc, MPS_INFO, "%s: IOCStatus %04x SASStatus %02x\n",
__func__, le16toh(rpl->IOCStatus), rpl->SASStatus);
***************
*** 2774,2780 ****
MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE | MPI2_SGLFLAGS_SGL_TYPE_MPI;
mps_dprint(sc, MPS_INFO, "%s: sending SMP request to SAS "
! "address %#jx\n", __func__, (uintmax_t)sasaddr);
mpi_init_sge(cm, req, &req->SGL);
--- 2811,2817 ----
MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE | MPI2_SGLFLAGS_SGL_TYPE_MPI;
mps_dprint(sc, MPS_INFO, "%s: sending SMP request to SAS "
! "address %#jx\n", __func__, (uintmax_t)sasaddr);
mpi_init_sge(cm, req, &req->SGL);
***************
*** 2992,2998 ****
sc = sassc->sc;
tm = mps_alloc_command(sc);
if (tm == NULL) {
! mps_printf(sc, "comand alloc failure in mpssas_action_resetdev\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
xpt_done(ccb);
return;
--- 3029,3036 ----
sc = sassc->sc;
tm = mps_alloc_command(sc);
if (tm == NULL) {
! mps_printf(sc, "comand alloc failure in "
! "mpssas_action_resetdev\n");
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
xpt_done(ccb);
return;
***************
*** 3080,3193 ****
}
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_INFO, "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_dprint(sc, MPS_TRACE, "%s\n", __func__);
-
- 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_TRACE, "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_TRACE, "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_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
-
- 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_INFO, "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)
{
--- 3118,3123 ----
***************
*** 3196,3201 ****
--- 3126,3133 ----
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;
***************
*** 3218,3230 ****
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)];
--- 3150,3155 ----
***************
*** 3275,3452 ****
}
break;
}
default:
break;
}
}
- #else /* __FreeBSD_version >= 1000006 */
static void
! mpssas_check_eedp(struct mpssas_softc *sassc)
{
! struct mps_softc *sc = sassc->sc;
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);
target_id_t targetid;
lun_id_t lunid;
! struct cam_periph *found_periph;
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;
! }
! lunid = 0;
! do {
! ccb = xpt_alloc_ccb_nowait();
! if (ccb == NULL) {
! mps_dprint(sc, MPS_FAULT, "Unable to alloc CCB "
! "for EEDP support.\n");
! return;
! }
! if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
! pathid, targetid, lunid) != CAM_REQ_CMP) {
! mps_dprint(sc, MPS_FAULT, "Unable to create "
! "path for EEDP support\n");
! xpt_free_ccb(ccb);
! 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_FAULT,
! "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);
! /*
! * 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
! */
! xpt_path_string(ccb->ccb_h.path, path_str,
! sizeof(path_str));
! 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_INFO,
! "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_FAULT, "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);
!
! /*
! * 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);
! }
}
-
static void
mpssas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
{
--- 3200,3347 ----
}
break;
}
+ #else
+ case AC_FOUND_DEVICE: {
+ struct ccb_getdev *cgd;
+
+ cgd = arg;
+ mpssas_check_eedp(sc, path, cgd);
+ break;
+ }
+ #endif
default:
break;
}
}
+ #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)
{
! struct mpssas_softc *sassc = sc->sassc;
struct ccb_scsiio *csio;
struct scsi_read_capacity_16 *scsi_cmd;
struct scsi_read_capacity_eedp *rcap_buf;
! path_id_t pathid;
target_id_t targetid;
lun_id_t lunid;
! union ccb *ccb;
! struct cam_path *local_path;
struct mpssas_target *target;
struct mpssas_lun *lun;
uint8_t found_lun;
char path_str[64];
+ sassc = sc->sassc;
+ pathid = cam_sim_path(sassc->sim);
+ targetid = xpt_path_target_id(path);
+ lunid = xpt_path_lun_id(path);
+
+ target = &sassc->targets[targetid];
+ if (target->handle == 0x0)
+ 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;
! /*
! * 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_FAULT,
! "Unable to alloc CCB for EEDP support.\n");
! return;
! }
! if (xpt_create_path(&local_path, xpt_periph,
! pathid, targetid, lunid) != CAM_REQ_CMP) {
! mps_dprint(sc, MPS_FAULT,
! "Unable to create path for EEDP support\n");
! xpt_free_ccb(ccb);
! return;
! }
! /*
! * 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_FAULT,
! "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);
! }
! 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);
! /*
! * 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)
{
***************
*** 3499,3504 ****
--- 3394,3403 ----
}
if (rcap_buf->protect & 0x01) {
+ mps_dprint(sassc->sc, MPS_INFO, "LUN %d for "
+ "target ID %d is formatted for EEDP "
+ "support.\n", done_ccb->ccb_h.target_lun,
+ done_ccb->ccb_h.target_id);
lun->eedp_formatted = TRUE;
lun->eedp_block_size = scsi_4btoul(rcap_buf->length);
}
***************
*** 3510,3516 ****
xpt_free_path(done_ccb->ccb_h.path);
xpt_free_ccb(done_ccb);
}
! #endif /* __FreeBSD_version >= 1000006 */
int
mpssas_startup(struct mps_softc *sc)
--- 3409,3416 ----
xpt_free_path(done_ccb->ccb_h.path);
xpt_free_ccb(done_ccb);
}
! #endif /* (__FreeBSD_version < 901503) || \
! ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) */
int
mpssas_startup(struct mps_softc *sc)
*** src/sys/dev/mps/mps_sas.h.orig
--- src/sys/dev/mps/mps_sas.h
***************
*** 87,93 ****
#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;
--- 87,92 ----
***************
*** 101,109 ****
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;
--- 100,105 ----
*** src/sys/dev/mps/mps_sas_lsi.c.orig
--- src/sys/dev/mps/mps_sas_lsi.c
***************
*** 699,705 ****
--- 699,709 ----
mps_dprint(sc, MPS_INFO, "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 < 9010506) || \
+ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000036)))
if ((sassc->flags & MPSSAS_IN_STARTUP) == 0)
+ #endif
mpssas_rescan_target(sc, targ);
mps_dprint(sc, MPS_INFO, "Target id 0x%x added\n", targ->tid);
out:
***************
*** 818,829 ****
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = buffer;
cm->cm_length = htole32(sz);
! error = mps_request_polled(sc, cm);
reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /* If the poll returns error then we need to do diag reset */
! printf("%s: poll for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
--- 822,836 ----
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = buffer;
cm->cm_length = htole32(sz);
! error = mps_wait_command(sc, cm, 60, CAN_SLEEP);
reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
! /*
! * If the request returns an error then we need to do a diag
! * reset
! */
! printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
goto out;
***************
*** 955,961 ****
action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
! mps_request_polled(sc, cm);
mps_unlock(sc);
/*
--- 962,968 ----
action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
! mps_wait_command(sc, cm, 5, CAN_SLEEP);
mps_unlock(sc);
/*
*** src/sys/dev/mps/mps_user.c.orig
--- src/sys/dev/mps/mps_user.c
***************
*** 672,678 ****
cm = mps_alloc_command(sc);
if (cm == NULL) {
! mps_printf(sc, "mps_user_command: no mps requests\n");
err = ENOMEM;
goto Ret;
}
--- 672,678 ----
cm = mps_alloc_command(sc);
if (cm == NULL) {
! mps_printf(sc, "%s: no mps requests\n", __func__);
err = ENOMEM;
goto Ret;
}
***************
*** 680,687 ****
hdr = (MPI2_REQUEST_HEADER *)cm->cm_req;
! mps_dprint(sc, MPS_INFO, "mps_user_command: req %p %d rpl %p %d\n",
! cmd->req, cmd->req_len, cmd->rpl, cmd->rpl_len );
if (cmd->req_len > (int)sc->facts->IOCRequestFrameSize * 4) {
err = EINVAL;
--- 680,687 ----
hdr = (MPI2_REQUEST_HEADER *)cm->cm_req;
! mps_dprint(sc, MPS_INFO, "%s: req %p %d rpl %p %d\n", __func__,
! cmd->req, cmd->req_len, cmd->rpl, cmd->rpl_len);
if (cmd->req_len > (int)sc->facts->IOCRequestFrameSize * 4) {
err = EINVAL;
***************
*** 691,698 ****
if (err != 0)
goto RetFreeUnlocked;
! mps_dprint(sc, MPS_INFO, "mps_user_command: Function %02X "
! "MsgFlags %02X\n", hdr->Function, hdr->MsgFlags );
err = mps_user_setup_request(cm, cmd);
if (err != 0) {
--- 691,698 ----
if (err != 0)
goto RetFreeUnlocked;
! mps_dprint(sc, MPS_INFO, "%s: Function %02X MsgFlags %02X\n", __func__,
! hdr->Function, hdr->MsgFlags);
err = mps_user_setup_request(cm, cmd);
if (err != 0) {
***************
*** 718,725 ****
cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
mps_lock(sc);
! err = mps_wait_command(sc, cm, 30);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n",
--- 718,734 ----
cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
+ err = mps_user_setup_request(cm, cmd);
+ if (err == EINVAL) {
+ mps_printf(sc, "%s: unsupported parameter or unsupported "
+ "function in request (function = 0x%X)\n", __func__,
+ hdr->Function);
+ }
+ if (err != 0)
+ goto RetFreeUnlocked;
+
mps_lock(sc);
! err = mps_wait_command(sc, cm, 60, CAN_SLEEP);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n",
***************
*** 731,740 ****
sz = rpl->MsgLength * 4;
if (sz > cmd->rpl_len) {
! mps_printf(sc,
! "mps_user_command: reply buffer too small %d required %d\n",
! cmd->rpl_len, sz );
! err = EINVAL;
sz = cmd->rpl_len;
}
--- 740,747 ----
sz = rpl->MsgLength * 4;
if (sz > cmd->rpl_len) {
! mps_printf(sc, "%s: user reply buffer (%d) smaller than "
! "returned buffer (%d)\n", __func__, cmd->rpl_len, sz);
sz = cmd->rpl_len;
}
***************
*** 742,748 ****
copyout(rpl, cmd->rpl, sz);
if (buf != NULL)
copyout(buf, cmd->buf, cmd->len);
! mps_dprint(sc, MPS_INFO, "mps_user_command: reply size %d\n", sz );
RetFreeUnlocked:
mps_lock(sc);
--- 749,755 ----
copyout(rpl, cmd->rpl, sz);
if (buf != NULL)
copyout(buf, cmd->buf, cmd->len);
! mps_dprint(sc, MPS_INFO, "%s: reply size %d\n", __func__, sz);
RetFreeUnlocked:
mps_lock(sc);
***************
*** 849,855 ****
cm->cm_complete = NULL;
cm->cm_complete_data = NULL;
! err = mps_wait_command(sc, cm, 30);
if (err != 0) {
err = EIO;
--- 856,862 ----
cm->cm_complete = NULL;
cm->cm_complete_data = NULL;
! err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
if (err != 0) {
err = EIO;
***************
*** 864,878 ****
sz = rpl->MsgLength * 4;
if (sz > data->ReplySize) {
! mps_printf(sc, "%s: reply buffer too small: %d, "
! "required: %d\n", __func__, data->ReplySize, sz);
! err = EINVAL;
! } else {
! mps_unlock(sc);
! copyout(cm->cm_reply, PTRIN(data->PtrReply),
! data->ReplySize);
! mps_lock(sc);
}
}
mpssas_free_tm(sc, cm);
goto Ret;
--- 871,884 ----
sz = rpl->MsgLength * 4;
if (sz > data->ReplySize) {
! mps_printf(sc, "%s: user reply buffer (%d) "
! "smaller than returned buffer (%d)\n",
! __func__, data->ReplySize, sz);
}
+ mps_unlock(sc);
+ copyout(cm->cm_reply, PTRIN(data->PtrReply),
+ data->ReplySize);
+ mps_lock(sc);
}
mpssas_free_tm(sc, cm);
goto Ret;
***************
*** 986,992 ****
mps_lock(sc);
! err = mps_wait_command(sc, cm, 30);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
--- 992,998 ----
mps_lock(sc);
! err = mps_wait_command(sc, cm, 30, CAN_SLEEP);
if (err) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
***************
*** 1025,1039 ****
sz = rpl->MsgLength * 4;
if (sz > data->ReplySize) {
! mps_printf(sc, "%s: reply buffer too small: %d, "
! "required: %d\n", __func__, data->ReplySize, sz);
! err = EINVAL;
! } else {
! mps_unlock(sc);
! copyout(cm->cm_reply, PTRIN(data->PtrReply),
! data->ReplySize);
! mps_lock(sc);
}
if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
(function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
--- 1031,1043 ----
sz = rpl->MsgLength * 4;
if (sz > data->ReplySize) {
! mps_printf(sc, "%s: user reply buffer (%d) smaller "
! "than returned buffer (%d)\n", __func__,
! data->ReplySize, sz);
}
+ mps_unlock(sc);
+ copyout(cm->cm_reply, PTRIN(data->PtrReply), data->ReplySize);
+ mps_lock(sc);
if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
(function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
***************
*** 1203,1209 ****
/*
* Send command synchronously.
*/
! status = mps_wait_command(sc, cm, 30);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
--- 1207,1213 ----
/*
* Send command synchronously.
*/
! status = mps_wait_command(sc, cm, 30, CAN_SLEEP);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
***************
*** 1252,1259 ****
*/
*return_code = MPS_FW_DIAG_ERROR_RELEASE_FAILED;
if (!pBuffer->enabled) {
! mps_dprint(sc, MPS_INFO, "%s: This buffer type is not supported "
! "by the IOC", __func__);
return (MPS_DIAG_FAILURE);
}
--- 1256,1263 ----
*/
*return_code = MPS_FW_DIAG_ERROR_RELEASE_FAILED;
if (!pBuffer->enabled) {
! mps_dprint(sc, MPS_INFO, "%s: This buffer type is not "
! "supported by the IOC", __func__);
return (MPS_DIAG_FAILURE);
}
***************
*** 1287,1293 ****
/*
* Send command synchronously.
*/
! status = mps_wait_command(sc, cm, 30);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
--- 1291,1297 ----
/*
* Send command synchronously.
*/
! status = mps_wait_command(sc, cm, 30, CAN_SLEEP);
if (status) {
mps_printf(sc, "%s: invalid request: error %d\n", __func__,
status);
*** src/sys/dev/mps/mpsvar.h.orig
--- src/sys/dev/mps/mpsvar.h
***************
*** 26,38 ****
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
! * $FreeBSD: stable/9/sys/dev/mps/mpsvar.h 251874 2013-06-18 00:36:53Z scottl $
*/
#ifndef _MPSVAR_H
#define _MPSVAR_H
! #define MPS_DRIVER_VERSION "14.00.00.01-fbsd"
#define MPS_DB_MAX_WAIT 2500
--- 26,38 ----
*
* LSI MPT-Fusion Host Adapter FreeBSD
*
! * $FreeBSD: head/sys/dev/mps/mpsvar.h 246713 2013-02-12 16:57:20Z kib $
*/
#ifndef _MPSVAR_H
#define _MPSVAR_H
! #define MPS_DRIVER_VERSION "16.00.00.00-fbsd"
#define MPS_DB_MAX_WAIT 2500
***************
*** 304,310 ****
bus_dma_tag_t buffer_dmat;
MPI2_IOC_FACTS_REPLY *facts;
- MPI2_PORT_FACTS_REPLY *pfacts;
int num_reqs;
int num_replies;
int fqdepth; /* Free queue */
--- 304,309 ----
***************
*** 628,642 ****
static __inline void
mps_from_u64(uint64_t data, U64 *mps)
{
! (mps)->High = (uint32_t)((data) >> 32);
! (mps)->Low = (uint32_t)((data) & 0xffffffff);
}
static __inline uint64_t
mps_to_u64(U64 *data)
{
! return (((uint64_t)data->High << 32) | data->Low);
}
static __inline void
--- 627,641 ----
static __inline void
mps_from_u64(uint64_t data, U64 *mps)
{
! (mps)->High = htole32((uint32_t)((data) >> 32));
! (mps)->Low = htole32((uint32_t)((data) & 0xffffffff));
}
static __inline uint64_t
mps_to_u64(U64 *data)
{
! return (((uint64_t)le32toh(data->High) << 32) | le32toh(data->Low));
}
static __inline void
***************
*** 686,692 ****
MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
int mps_map_command(struct mps_softc *sc, struct mps_command *cm);
! int mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout);
int mps_request_polled(struct mps_softc *sc, struct mps_command *cm);
int mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t
--- 685,692 ----
MPI2_EVENT_NOTIFICATION_REPLY *event_reply);
int mps_map_command(struct mps_softc *sc, struct mps_command *cm);
! int mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout,
! int sleep_flag);
int mps_request_polled(struct mps_softc *sc, struct mps_command *cm);
int mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t
*** src/sys/sys/param.h.orig
--- src/sys/sys/param.h
***************
*** 58,64 ****
* in the range 5 to 9.
*/
#undef __FreeBSD_version
! #define __FreeBSD_version 901505 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
--- 58,64 ----
* in the range 5 to 9.
*/
#undef __FreeBSD_version
! #define __FreeBSD_version 901506 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
More information about the svn-src-head
mailing list