Example #1
0
static void
ptinit(void)
{
	cam_status status;
	struct cam_path *path;

	/*
	 * Install a global async callback.  This callback will
	 * receive async callbacks like "new device found".
	 */
	status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);

	if (status == CAM_REQ_CMP) {
		struct ccb_setasync csa;

                xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
                csa.ccb_h.func_code = XPT_SASYNC_CB;
                csa.event_enable = AC_FOUND_DEVICE;
                csa.callback = ptasync;
                csa.callback_arg = NULL;
                xpt_action((union ccb *)&csa);
		status = csa.ccb_h.status;
                xpt_free_path(path);
        }

	if (status != CAM_REQ_CMP) {
		printf("pt: Failed to attach master async callback "
		       "due to status 0x%x!\n", status);
	}
}
Example #2
0
void
mpt_cam_detach(mpt_softc_t *mpt)
{
	if (mpt->sim != NULL) {
		xpt_free_path(mpt->path);
		xpt_bus_deregister(cam_sim_path(mpt->sim));
		cam_sim_free(mpt->sim, TRUE);
		mpt->sim = NULL;
	}
}
Example #3
0
/**
 * mrsas_cam_detach:        De-allocates and teardown CAM  
 * input:                   Adapter instance soft state 
 *
 * De-registers and frees the paths and SIMs. 
 */
void mrsas_cam_detach(struct mrsas_softc *sc)
{
	if (sc->ev_tq != NULL)
        taskqueue_free(sc->ev_tq);
    mtx_lock(&sc->sim_lock);
    if (sc->path_0)
        xpt_free_path(sc->path_0);
    if (sc->sim_0) {
        xpt_bus_deregister(cam_sim_path(sc->sim_0));
        cam_sim_free(sc->sim_0, FALSE);
    }
    if (sc->path_1)
        xpt_free_path(sc->path_1);
    if (sc->sim_1) {
        xpt_bus_deregister(cam_sim_path(sc->sim_1));
        cam_sim_free(sc->sim_1, TRUE);
    }
    mtx_unlock(&sc->sim_lock);
}
/**
 * mrsas_cam_detach:        De-allocates and teardown CAM  
 * input:                   Adapter instance soft state 
 *
 * De-registers and frees the paths and SIMs. 
 */
void mrsas_cam_detach(struct mrsas_softc *sc)
{
    if (sc->ev_tq != NULL)
        taskqueue_free(sc->ev_tq);
    lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
    if (sc->path_0)
        xpt_free_path(sc->path_0);
    if (sc->sim_0) {
        xpt_bus_deregister(cam_sim_path(sc->sim_0));
        cam_sim_free(sc->sim_0);
    }
    if (sc->path_1)
        xpt_free_path(sc->path_1);
    if (sc->sim_1) {
        xpt_bus_deregister(cam_sim_path(sc->sim_1));
        cam_sim_free(sc->sim_1);
    }
    lockmgr(&sc->sim_lock, LK_RELEASE);
}
Example #5
0
/*
 * Function name:	twa_cam_detach
 * Description:		Detaches the driver from CAM.
 *
 * Input:		sc	-- ptr to per ctlr structure
 * Output:		None
 * Return value:	None
 */
void
twa_cam_detach(struct twa_softc *sc)
{
	if (sc->twa_path)
		xpt_free_path(sc->twa_path);
	if (sc->twa_sim) {
		xpt_bus_deregister(cam_sim_path(sc->twa_sim));
		cam_sim_free(sc->twa_sim, TRUE); /* passing TRUE will free the devq as well */
	}
}
Example #6
0
int
aha_detach(struct aha_softc *aha)
{
	mtx_lock(&aha->lock);
	xpt_async(AC_LOST_DEVICE, aha->path, NULL);
	xpt_free_path(aha->path);
	xpt_bus_deregister(cam_sim_path(aha->sim));
	cam_sim_free(aha->sim, /*free_devq*/TRUE);
	mtx_unlock(&aha->lock);
	/* XXX: Drain all timers? */
	return (0);
}
Example #7
0
/*
 * Function name:	twa_bus_scan_cb
 * Description:		Callback from CAM on a bus scan request.
 *
 * Input:		periph	-- we don't use this
 *			ccb	-- bus scan request ccb that we sent to CAM
 * Output:		None
 * Return value:	None
 */
static void
twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
{
	twa_dbg_print(3, "ccb = %p\n", ccb);
	if (ccb->ccb_h.status != CAM_REQ_CMP)
		printf("cam_scan_callback: failure status = %x\n",
					ccb->ccb_h.status);
	else
		twa_dbg_print(3, "success");

	xpt_free_path(ccb->ccb_h.path);
	free(ccb, M_TEMP);
}
Example #8
0
void
tws_cam_detach(struct tws_softc *sc)
{
    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    mtx_lock(&sc->sim_lock);
    if (sc->path)
        xpt_free_path(sc->path);
    if (sc->sim) {
        xpt_bus_deregister(cam_sim_path(sc->sim));
        cam_sim_free(sc->sim, TRUE);
    }
    mtx_unlock(&sc->sim_lock);
}
Example #9
0
void
tws_cam_detach(struct tws_softc *sc)
{
    TWS_TRACE_DEBUG(sc, "entry", 0, 0);
    lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
    if (sc->path)
        xpt_free_path(sc->path);
    if (sc->sim) {
        xpt_bus_deregister(cam_sim_path(sc->sim));
        cam_sim_free(sc->sim);
    }
    lockmgr(&sc->sim_lock, LK_RELEASE);
}
Example #10
0
void
ic_lost_target(isc_session_t *sp, int target)
{
     debug_called(8);
     sdebug(2, "lost target=%d", target);

     if(sp->cam_path != NULL) {
	  mtx_lock(&sp->cam_mtx);
	  xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL);
	  xpt_free_path(sp->cam_path);
	  mtx_unlock(&sp->cam_mtx);
	  sp->cam_path = 0; // XXX
     }
}
Example #11
0
/*
 * Function name:	twa_bus_scan_cb
 * Description:		Callback from CAM on a bus scan request.
 *
 * Input:		periph	-- we don't use this
 *			ccb	-- bus scan request ccb that we sent to CAM
 * Output:		None
 * Return value:	None
 */
static TW_VOID
twa_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
{
	tw_osli_dbg_printf(3, "entering");

	if (ccb->ccb_h.status != CAM_REQ_CMP)
		kprintf("cam_scan_callback: failure status = %x\n",
			ccb->ccb_h.status);
	else
		tw_osli_dbg_printf(3, "success");

	xpt_free_path(ccb->ccb_h.path);
	kfree(ccb, M_TEMP);
}
Example #12
0
static void
nvme_sim_controller_fail(void *ctrlr_arg)
{
	struct nvme_sim_softc *sc = ctrlr_arg;
	struct nvme_controller *ctrlr = sc->s_ctrlr;

	mtx_lock(&ctrlr->lock);
	xpt_async(AC_LOST_DEVICE, sc->s_path, NULL);
	xpt_free_path(sc->s_path);
	xpt_bus_deregister(cam_sim_path(sc->s_sim));
	cam_sim_free(sc->s_sim, /*free_devq*/TRUE);
	mtx_unlock(&ctrlr->lock);
	free(sc, M_NVME);
}
Example #13
0
void
isci_remote_device_release_lun_queue(struct ISCI_REMOTE_DEVICE *remote_device,
    lun_id_t lun)
{
	if (remote_device->frozen_lun_mask & (1 << lun)) {
		struct cam_path *path;

		remote_device->frozen_lun_mask &= ~(1 << lun);
		xpt_create_path(&path, NULL,
		    cam_sim_path(remote_device->domain->controller->sim),
		    remote_device->index, lun);
		xpt_release_devq(path, 1, TRUE);
		xpt_free_path(path);
	}
}
Example #14
0
/********************************************************************************
 * Find a peripheral attahed at (bus),(target)
 */
static struct cam_periph *
mly_find_periph(struct mly_softc *sc, int bus, int target)
{
    struct cam_periph	*periph;
    struct cam_path	*path;
    int			status;

    status = xpt_create_path(&path, NULL, cam_sim_path(sc->mly_cam_sim[bus]), target, 0);
    if (status == CAM_REQ_CMP) {
	periph = cam_periph_find(path, NULL);
	xpt_free_path(path);
    } else {
	periph = NULL;
    }
    return(periph);
}
Example #15
0
/*
 * Function name:	tw_osli_cam_detach
 * Description:		Detaches the driver from CAM.
 *
 * Input:		sc	-- ptr to OSL internal ctlr context
 * Output:		None
 * Return value:	None
 */
TW_VOID
tw_osli_cam_detach(struct twa_softc *sc)
{
	tw_osli_dbg_dprintf(3, sc, "entered");

	mtx_lock(sc->sim_lock);
           
	if (sc->path)
		xpt_free_path(sc->path);
	if (sc->sim) {
		xpt_bus_deregister(cam_sim_path(sc->sim));
		/* Passing TRUE to cam_sim_free will free the devq as well. */
		cam_sim_free(sc->sim, TRUE);
	}
	/* It's ok have 1 hold count while destroying the mutex */
	mtx_destroy(sc->sim_lock);
}
Example #16
0
int os_query_remove_device(void *osext, int id)
{
	PVBUS_EXT				vbus_ext = (PVBUS_EXT)osext;
	struct cam_periph		*periph = NULL;
    struct cam_path			*path;
    int						status,retval = 0;

    status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0);
    if (status == CAM_REQ_CMP) {
		if((periph = cam_periph_find(path, "da")) != NULL){
			if(periph->refcount >= 1)	
				retval = -1;
		}
		xpt_free_path(path);
    }

    return retval;
}
Example #17
0
static void
tws_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
{
    struct tws_softc *sc = periph->softc;

    /* calling trace results in non-sleepable lock head panic
       using printf to debug */

    if (ccb->ccb_h.status != CAM_REQ_CMP) {
        kprintf("cam_scan failure\n");

        lockmgr(&sc->gen_lock, LK_EXCLUSIVE);
        tws_send_event(sc, TWS_SCAN_FAILURE);
        lockmgr(&sc->gen_lock, LK_RELEASE);
    }

    xpt_free_path(ccb->ccb_h.path);
}
Example #18
0
static void
pmprelease(struct cam_periph *periph, int mask)
{
	struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
	struct cam_path *dpath;
	int i;

	mask &= softc->frozen;
	for (i = 0; i < 15; i++) {
		if ((mask & (1 << i)) == 0)
			continue;
		if (xpt_create_path(&dpath, periph,
		    xpt_path_path_id(periph->path),
		    i, 0) == CAM_REQ_CMP) {
			softc->frozen &= ~(1 << i);
			cam_release_devq(dpath, 0, 0, 0, FALSE);
			xpt_release_device(dpath->device);
			xpt_free_path(dpath);
		}
	}
}
Example #19
0
static void
pmponinvalidate(struct cam_periph *periph)
{
	struct cam_path *dpath;
	int i;

	/*
	 * De-register any async callbacks.
	 */
	xpt_register_async(0, pmpasync, periph, periph->path);

	for (i = 0; i < 15; i++) {
		if (xpt_create_path(&dpath, periph,
		    xpt_path_path_id(periph->path),
		    i, 0) == CAM_REQ_CMP) {
			xpt_async(AC_LOST_DEVICE, dpath, NULL);
			xpt_free_path(dpath);
		}
	}
	pmprelease(periph, -1);
}
Example #20
0
static int
aac_cam_detach(device_t dev)
{
    struct aac_softc *sc;
    struct aac_cam *camsc;
    fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");

    camsc = (struct aac_cam *)device_get_softc(dev);
    sc = camsc->inf->aac_sc;

    mtx_lock(&sc->aac_io_lock);

    xpt_async(AC_LOST_DEVICE, camsc->path, NULL);
    xpt_free_path(camsc->path);
    xpt_bus_deregister(cam_sim_path(camsc->sim));
    cam_sim_free(camsc->sim, /*free_devq*/TRUE);

    mtx_unlock(&sc->aac_io_lock);

    return (0);
}
Example #21
0
void
ic_destroy(isc_session_t *sp )
{
     debug_called(8);

     if(sp->cam_path != NULL) {
	  sdebug(2, "name=%s unit=%d",
		 cam_sim_name(sp->cam_sim), cam_sim_unit(sp->cam_sim));
	  CAM_LOCK(sp);
#if 0
	  xpt_async(AC_LOST_DEVICE, sp->cam_path, NULL);
#else
	  xpt_async(XPT_RESET_BUS, sp->cam_path, NULL);
#endif
	  xpt_free_path(sp->cam_path);
	  xpt_bus_deregister(cam_sim_path(sp->cam_sim));
	  cam_sim_free(sp->cam_sim, TRUE /*free_devq*/);

	  CAM_UNLOCK(sp);
	  sdebug(2, "done");
     }
}
Example #22
0
static void
pmpfreeze(struct cam_periph *periph, int mask)
{
	struct pmp_softc *softc = (struct pmp_softc *)periph->softc;
	struct cam_path *dpath;
	int i;

	mask &= ~softc->frozen;
	for (i = 0; i < 15; i++) {
		if ((mask & (1 << i)) == 0)
			continue;
		if (xpt_create_path(&dpath, periph,
		    xpt_path_path_id(periph->path),
		    i, 0) == CAM_REQ_CMP) {
			softc->frozen |= (1 << i);
			xpt_acquire_device(dpath->device);
			cam_freeze_devq_arg(dpath,
			    RELSIM_RELEASE_RUNLEVEL, CAM_RL_BUS + 1);
			xpt_free_path(dpath);
		}
	}
}
Example #23
0
int
ata_detach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);

    /* check that we have a valid channel to detach */
    if (!ch->r_irq)
	return ENXIO;

    /* grap the channel lock so no new requests gets launched */
    mtx_lock(&ch->state_mtx);
    ch->state |= ATA_STALL_QUEUE;
    mtx_unlock(&ch->state_mtx);
    if (ch->flags & ATA_PERIODIC_POLL)
	callout_drain(&ch->poll_callout);

    taskqueue_drain(taskqueue_thread, &ch->conntask);

	mtx_lock(&ch->state_mtx);
	xpt_async(AC_LOST_DEVICE, ch->path, NULL);
	xpt_free_path(ch->path);
	xpt_bus_deregister(cam_sim_path(ch->sim));
	cam_sim_free(ch->sim, /*free_devq*/TRUE);
	ch->sim = NULL;
	mtx_unlock(&ch->state_mtx);

    /* release resources */
    bus_teardown_intr(dev, ch->r_irq, ch->ih);
    bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
    ch->r_irq = NULL;

    /* free DMA resources if DMA HW present*/
    if (ch->dma.free)
	ch->dma.free(dev);

    mtx_destroy(&ch->state_mtx);
    return 0;
}
Example #24
0
static void
mpssas_stop_unit_done(struct cam_periph *periph, union ccb *done_ccb)
{
	struct mpssas_softc *sassc;
	char path_str[64];

	sassc = (struct mpssas_softc *)done_ccb->ccb_h.ppriv_ptr1;

	xpt_path_string(done_ccb->ccb_h.path, path_str, sizeof(path_str));
	mps_dprint(sassc->sc, MPS_INFO, "Completing stop unit for %s\n",
	    path_str);

	if (done_ccb == NULL)
		return;

	/*
	 * Nothing more to do except free the CCB and path.  If the command
	 * timed out, an abort reset, then target reset will be issued during
	 * the SCSI Command process.
	 */
	xpt_free_path(done_ccb->ccb_h.path);
	xpt_free_ccb(done_ccb);
}
Example #25
0
/*
 * The state of the port has changed.
 *
 * If atx is NULL the physical port has changed state.
 * If atx is non-NULL a particular target behind a PM has changed state.
 *
 * If found is -1 the target state must be queued to a non-interrupt context.
 * (only works with at == NULL).
 *
 * If found is 0 the target was removed.
 * If found is 1 the target was inserted.
 */
void
ahci_cam_changed(struct ahci_port *ap, struct ata_port *atx, int found)
{
	struct cam_path *tmppath;
	int status;
	int target;

	target = atx ? atx->at_target : CAM_TARGET_WILDCARD;

	if (ap->ap_sim == NULL)
		return;
	if (found == CAM_TARGET_WILDCARD) {
		status = xpt_create_path(&tmppath, NULL,
					 cam_sim_path(ap->ap_sim),
					 target, CAM_LUN_WILDCARD);
		if (status != CAM_REQ_CMP)
			return;
		ahci_cam_rescan(ap);
	} else {
		status = xpt_create_path(&tmppath, NULL,
					 cam_sim_path(ap->ap_sim),
					 target,
					 CAM_LUN_WILDCARD);
		if (status != CAM_REQ_CMP)
			return;
#if 0
		/*
		 * This confuses CAM
		 */
		if (found)
			xpt_async(AC_FOUND_DEVICE, tmppath, NULL);
		else
			xpt_async(AC_LOST_DEVICE, tmppath, NULL);
#endif
	}
	xpt_free_path(tmppath);
}
Example #26
0
static int
ahci_em_detach(device_t dev)
{
	struct ahci_enclosure *enc = device_get_softc(dev);
	int i;

	for (i = 0; i < enc->channels * AHCI_NUM_LEDS; i++) {
		if (enc->leds[i].led)
			led_destroy(enc->leds[i].led);
	}
	mtx_lock(&enc->mtx);
	xpt_async(AC_LOST_DEVICE, enc->path, NULL);
	xpt_free_path(enc->path);
	xpt_bus_deregister(cam_sim_path(enc->sim));
	cam_sim_free(enc->sim, /*free_devq*/TRUE);
	mtx_unlock(&enc->mtx);

	bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
	bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt);
	if (enc->r_memr)
		bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr);
	mtx_destroy(&enc->mtx);
	return (0);
}
Example #27
0
static int
isci_detach(device_t device)
{
    struct isci_softc *isci = DEVICE2SOFTC(device);
    int i, phy;

    for (i = 0; i < isci->controller_count; i++) {
        struct ISCI_CONTROLLER *controller = &isci->controllers[i];
        SCI_STATUS status;
        void *unmap_buffer;

        if (controller->scif_controller_handle != NULL) {
            scic_controller_disable_interrupts(
                scif_controller_get_scic_handle(controller->scif_controller_handle));

            mtx_lock(&controller->lock);
            status = scif_controller_stop(controller->scif_controller_handle, 0);
            mtx_unlock(&controller->lock);

            while (controller->is_started == TRUE) {
                /* Now poll for interrupts until the controller stop complete
                 *  callback is received.
                 */
                mtx_lock(&controller->lock);
                isci_interrupt_poll_handler(controller);
                mtx_unlock(&controller->lock);
                pause("isci", 1);
            }

            if(controller->sim != NULL) {
                mtx_lock(&controller->lock);
                xpt_free_path(controller->path);
                xpt_bus_deregister(cam_sim_path(controller->sim));
                cam_sim_free(controller->sim, TRUE);
                mtx_unlock(&controller->lock);
            }
        }

        if (controller->timer_memory != NULL)
            free(controller->timer_memory, M_ISCI);

        if (controller->remote_device_memory != NULL)
            free(controller->remote_device_memory, M_ISCI);

        for (phy = 0; phy < SCI_MAX_PHYS; phy++) {
            if (controller->phys[phy].cdev_fault)
                led_destroy(controller->phys[phy].cdev_fault);

            if (controller->phys[phy].cdev_locate)
                led_destroy(controller->phys[phy].cdev_locate);
        }

        while (1) {
            sci_pool_get(controller->unmap_buffer_pool, unmap_buffer);
            if (unmap_buffer == NULL)
                break;
            contigfree(unmap_buffer, PAGE_SIZE, M_ISCI);
        }
    }

    /* The SCIF controllers have been stopped, so we can now
     *  free the SCI library memory.
     */
    if (isci->sci_library_memory != NULL)
        free(isci->sci_library_memory, M_ISCI);

    for (i = 0; i < ISCI_NUM_PCI_BARS; i++)
    {
        struct ISCI_PCI_BAR *pci_bar = &isci->pci_bar[i];

        if (pci_bar->resource != NULL)
            bus_release_resource(device, SYS_RES_MEMORY,
                                 pci_bar->resource_id, pci_bar->resource);
    }

    for (i = 0; i < isci->num_interrupts; i++)
    {
        struct ISCI_INTERRUPT_INFO *interrupt_info;

        interrupt_info = &isci->interrupt_info[i];

        if(interrupt_info->tag != NULL)
            bus_teardown_intr(device, interrupt_info->res,
                              interrupt_info->tag);

        if(interrupt_info->res != NULL)
            bus_release_resource(device, SYS_RES_IRQ,
                                 rman_get_rid(interrupt_info->res),
                                 interrupt_info->res);

        pci_release_msi(device);
    }
    pci_disable_busmaster(device);

    return (0);
}
Example #28
0
void
isp_attach(struct ispsoftc *isp)
{
	int primary, secondary;
	struct ccb_setasync csa;
	struct cam_devq *devq;
	struct cam_sim *sim;
	struct cam_path *path;

	/*
	 * Establish (in case of 12X0) which bus is the primary.
	 */

	primary = 0;
	secondary = 1;

	/*
	 * Create the device queue for our SIM(s).
	 */
	devq = cam_simq_alloc(MAXISPREQUEST);
	if (devq == NULL) {
		return;
	}

	/*
	 * Construct our SIM entry.
	 */
	sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
	    isp->isp_unit, 1, MAXISPREQUEST, devq);
	if (sim == NULL) {
		cam_simq_free(devq);
		return;
	}
	if (xpt_bus_register(sim, primary) != CAM_SUCCESS) {
		cam_sim_free(sim, TRUE);
		return;
	}

	if (xpt_create_path(&path, NULL, cam_sim_path(sim),
	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
		xpt_bus_deregister(cam_sim_path(sim));
		cam_sim_free(sim, TRUE);
		return;
	}

	xpt_setup_ccb(&csa.ccb_h, path, 5);
	csa.ccb_h.func_code = XPT_SASYNC_CB;
	csa.event_enable = AC_LOST_DEVICE;
	csa.callback = isp_cam_async;
	csa.callback_arg = sim;
	xpt_action((union ccb *)&csa);
	isp->isp_sim = sim;
	isp->isp_path = path;

	/*
	 * If we have a second channel, construct SIM entry for that.
	 */
	if (IS_12X0(isp)) {
		sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp,
		    isp->isp_unit, 1, MAXISPREQUEST, devq);
		if (sim == NULL) {
			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
			xpt_free_path(isp->isp_path);
			cam_simq_free(devq);
			return;
		}
		if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) {
			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
			xpt_free_path(isp->isp_path);
			cam_sim_free(sim, TRUE);
			return;
		}

		if (xpt_create_path(&path, NULL, cam_sim_path(sim),
		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
			xpt_bus_deregister(cam_sim_path(isp->isp_sim));
			xpt_free_path(isp->isp_path);
			xpt_bus_deregister(cam_sim_path(sim));
			cam_sim_free(sim, TRUE);
			return;
		}

		xpt_setup_ccb(&csa.ccb_h, path, 5);
		csa.ccb_h.func_code = XPT_SASYNC_CB;
		csa.event_enable = AC_LOST_DEVICE;
		csa.callback = isp_cam_async;
		csa.callback_arg = sim;
		xpt_action((union ccb *)&csa);
		isp->isp_sim2 = sim;
		isp->isp_path2 = path;
	}
	if (isp->isp_state == ISP_INITSTATE)
		isp->isp_state = ISP_RUNSTATE;
}
static void
mrsas_rescan_callback(struct cam_periph *periph, union ccb *ccb)
{
	xpt_free_path(ccb->ccb_h.path);
	xpt_free_ccb(ccb);
}
Example #30
0
static void
ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code)
{
	union  ccb	  *ccb;
	struct ccb_scsiio *csio;

	ccb = accb->ccb;
	csio = &accb->ccb->csio;

	if ((accb->flags & ACCB_ACTIVE) == 0) {
		device_printf(aha->dev, 
		    "ahadone - Attempt to free non-active ACCB %p\n",
		    (void *)accb);
		return;
	}

	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
		bus_dmasync_op_t op;

		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
			op = BUS_DMASYNC_POSTREAD;
		else
			op = BUS_DMASYNC_POSTWRITE;
		bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op);
		bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
	}

	if (accb == aha->recovery_accb) {
		/*
		 * The recovery ACCB does not have a CCB associated
		 * with it, so short circuit the normal error handling.
		 * We now traverse our list of pending CCBs and process
		 * any that were terminated by the recovery CCBs action.
		 * We also reinstate timeouts for all remaining, pending,
		 * CCBs.
		 */
		struct cam_path *path;
		struct ccb_hdr *ccb_h;
		cam_status error;

		/* Notify all clients that a BDR occurred */
		error = xpt_create_path(&path, /*periph*/NULL,
		    cam_sim_path(aha->sim), accb->hccb.target,
		    CAM_LUN_WILDCARD);

		if (error == CAM_REQ_CMP) {
			xpt_async(AC_SENT_BDR, path, NULL);
			xpt_free_path(path);
		}

		ccb_h = LIST_FIRST(&aha->pending_ccbs);
		while (ccb_h != NULL) {
			struct aha_ccb *pending_accb;

			pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
			if (pending_accb->hccb.target == accb->hccb.target) {
				pending_accb->hccb.ahastat = AHASTAT_HA_BDR;
				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
				ahadone(aha, pending_accb, AMBI_ERROR);
			} else {
				callout_reset_sbt(&pending_accb->timer,
				    SBT_1MS * ccb_h->timeout, 0, ahatimeout,
				    pending_accb, 0);
				ccb_h = LIST_NEXT(ccb_h, sim_links.le);
			}
		}
		device_printf(aha->dev, "No longer in timeout\n");
		return;
	}

	callout_stop(&accb->timer);

	switch (comp_code) {
	case AMBI_FREE:
		device_printf(aha->dev,
		    "ahadone - CCB completed with free status!\n");
		break;
	case AMBI_NOT_FOUND:
		device_printf(aha->dev,
		    "ahadone - CCB Abort failed to find CCB\n");
		break;
	case AMBI_ABORT:
	case AMBI_ERROR:
		/* An error occurred */
		if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
			csio->resid = 0;
		else
			csio->resid = aha_a24tou(accb->hccb.data_len);
		switch(accb->hccb.ahastat) {
		case AHASTAT_DATARUN_ERROR:
		{
			if (csio->resid <= 0) {
				csio->ccb_h.status = CAM_DATA_RUN_ERR;
				break;
			}
			/* FALLTHROUGH */
		}
		case AHASTAT_NOERROR:
			csio->scsi_status = accb->hccb.sdstat;
			csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
			switch(csio->scsi_status) {
			case SCSI_STATUS_CHECK_COND:
			case SCSI_STATUS_CMD_TERMINATED:
				csio->ccb_h.status |= CAM_AUTOSNS_VALID;
				/*
				 * The aha writes the sense data at different
				 * offsets based on the scsi cmd len
				 */
				bcopy((caddr_t) &accb->hccb.scsi_cdb +
				    accb->hccb.cmd_len,
				    (caddr_t) &csio->sense_data,
				    accb->hccb.sense_len);
				break;
			default:
				break;
			case SCSI_STATUS_OK:
				csio->ccb_h.status = CAM_REQ_CMP;
				break;
			}
			break;
		case AHASTAT_SELTIMEOUT:
			csio->ccb_h.status = CAM_SEL_TIMEOUT;
			break;
		case AHASTAT_UNEXPECTED_BUSFREE:
			csio->ccb_h.status = CAM_UNEXP_BUSFREE;
			break;
		case AHASTAT_INVALID_PHASE:
			csio->ccb_h.status = CAM_SEQUENCE_FAIL;
			break;
		case AHASTAT_INVALID_ACTION_CODE:
			panic("%s: Inavlid Action code", aha_name(aha));
			break;
		case AHASTAT_INVALID_OPCODE:
			if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
				panic("%s: Invalid CCB Opcode %x hccb = %p",
				    aha_name(aha), accb->hccb.opcode,
				    &accb->hccb);
			device_printf(aha->dev,
			    "AHA-1540A compensation failed\n");
			xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
			csio->ccb_h.status = CAM_REQUEUE_REQ;
			break;
		case AHASTAT_LINKED_CCB_LUN_MISMATCH:
			/* We don't even support linked commands... */
			panic("%s: Linked CCB Lun Mismatch", aha_name(aha));
			break;
		case AHASTAT_INVALID_CCB_OR_SG_PARAM:
			panic("%s: Invalid CCB or SG list", aha_name(aha));
			break;
		case AHASTAT_HA_SCSI_BUS_RESET:
			if ((csio->ccb_h.status & CAM_STATUS_MASK)
			    != CAM_CMD_TIMEOUT)
				csio->ccb_h.status = CAM_SCSI_BUS_RESET;
			break;
		case AHASTAT_HA_BDR:
			if ((accb->flags & ACCB_DEVICE_RESET) == 0)
				csio->ccb_h.status = CAM_BDR_SENT;
			else
				csio->ccb_h.status = CAM_CMD_TIMEOUT;
			break;
		}
		if (csio->ccb_h.status != CAM_REQ_CMP) {
			xpt_freeze_devq(csio->ccb_h.path, /*count*/1);
			csio->ccb_h.status |= CAM_DEV_QFRZN;
		}
		if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
		ahafreeccb(aha, accb);
		xpt_done(ccb);
		break;
	case AMBI_OK:
		/* All completed without incident */
		/* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */
		/* I don't think so since it works???? */
		ccb->ccb_h.status |= CAM_REQ_CMP;
		if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
		ahafreeccb(aha, accb);
		xpt_done(ccb);
		break;
	}
}