MPSAFE atapi-cam
This commit is contained in:
parent
f9978195dc
commit
523b3dc425
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <cam/cam_periph.h>
|
||||
#include <cam/cam_sim.h>
|
||||
#include <cam/cam_xpt_sim.h>
|
||||
#include <cam/cam_xpt_periph.h>
|
||||
#include <cam/cam_debug.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
|
||||
@ -210,14 +211,16 @@ atapi_cam_attach(device_t dev)
|
||||
}
|
||||
|
||||
if ((sim = cam_sim_alloc(atapi_action, atapi_poll, "ata",
|
||||
(void *)scp, unit, &Giant, 1, 1, devq)) == NULL) {
|
||||
(void *)scp, unit, &scp->state_lock, 1, 1, devq)) == NULL) {
|
||||
error = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
scp->sim = sim;
|
||||
|
||||
mtx_lock(&scp->state_lock);
|
||||
if (xpt_bus_register(sim, 0) != CAM_SUCCESS) {
|
||||
error = EINVAL;
|
||||
mtx_unlock(&scp->state_lock);
|
||||
goto out;
|
||||
}
|
||||
scp->flags |= BUS_REGISTERED;
|
||||
@ -226,6 +229,7 @@ atapi_cam_attach(device_t dev)
|
||||
cam_sim_path(sim), CAM_TARGET_WILDCARD,
|
||||
CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
error = ENOMEM;
|
||||
mtx_unlock(&scp->state_lock);
|
||||
goto out;
|
||||
}
|
||||
scp->path = path;
|
||||
@ -235,6 +239,7 @@ atapi_cam_attach(device_t dev)
|
||||
setup_async_cb(scp, AC_LOST_DEVICE);
|
||||
reinit_bus(scp, cold ? BOOT_ATTACH : ATTACH);
|
||||
error = 0;
|
||||
mtx_unlock(&scp->state_lock);
|
||||
|
||||
out:
|
||||
if (error != 0)
|
||||
@ -248,10 +253,8 @@ atapi_cam_detach(device_t dev)
|
||||
{
|
||||
struct atapi_xpt_softc *scp = device_get_softc(dev);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
xpt_freeze_simq(scp->sim, 1 /*count*/);
|
||||
mtx_unlock(&Giant);
|
||||
mtx_lock(&scp->state_lock);
|
||||
xpt_freeze_simq(scp->sim, 1 /*count*/);
|
||||
scp->flags |= DETACHING;
|
||||
mtx_unlock(&scp->state_lock);
|
||||
free_softc(scp);
|
||||
@ -268,7 +271,9 @@ atapi_cam_reinit(device_t dev) {
|
||||
*/
|
||||
|
||||
if (scp != NULL) {
|
||||
mtx_lock(&scp->state_lock);
|
||||
reinit_bus(scp, RESET);
|
||||
mtx_unlock(&scp->state_lock);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -283,7 +288,6 @@ reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) {
|
||||
return;
|
||||
}
|
||||
|
||||
mtx_lock(&scp->state_lock);
|
||||
old_atadev[0] = scp->atadev[0];
|
||||
old_atadev[1] = scp->atadev[1];
|
||||
scp->atadev[0] = NULL;
|
||||
@ -303,7 +307,6 @@ reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) {
|
||||
}
|
||||
dev_changed = (old_atadev[0] != scp->atadev[0])
|
||||
|| (old_atadev[1] != scp->atadev[1]);
|
||||
mtx_unlock(&scp->state_lock);
|
||||
free(children, M_TEMP);
|
||||
|
||||
switch (reason) {
|
||||
@ -327,14 +330,12 @@ setup_async_cb(struct atapi_xpt_softc *scp, uint32_t events)
|
||||
{
|
||||
struct ccb_setasync csa;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
xpt_setup_ccb(&csa.ccb_h, scp->path, /*priority*/ 5);
|
||||
csa.ccb_h.func_code = XPT_SASYNC_CB;
|
||||
csa.event_enable = events;
|
||||
csa.callback = &atapi_async;
|
||||
csa.callback_arg = scp->sim;
|
||||
xpt_action((union ccb *) &csa);
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -377,11 +378,9 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
cpi->protocol_version = SCSI_REV_2;
|
||||
|
||||
if (softc->ata_ch && tid != CAM_TARGET_WILDCARD) {
|
||||
mtx_lock(&softc->state_lock);
|
||||
if (softc->atadev[tid] == NULL) {
|
||||
ccb->ccb_h.status = CAM_DEV_NOT_THERE;
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
switch (softc->atadev[ccb_h->target_id]->mode) {
|
||||
@ -414,7 +413,6 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&softc->state_lock);
|
||||
}
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
@ -425,7 +423,9 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
int tid = ccb_h->target_id;
|
||||
|
||||
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("dev reset\n"));
|
||||
mtx_unlock(&softc->state_lock);
|
||||
ata_controlcmd(softc->atadev[tid]->dev, ATA_DEVICE_RESET, 0, 0, 0);
|
||||
mtx_lock(&softc->state_lock);
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
@ -433,7 +433,9 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
|
||||
case XPT_RESET_BUS:
|
||||
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("bus reset\n"));
|
||||
mtx_unlock(&softc->state_lock);
|
||||
ata_reinit(softc->parent);
|
||||
mtx_lock(&softc->state_lock);
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
@ -475,18 +477,15 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
|
||||
CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("XPT_SCSI_IO\n"));
|
||||
|
||||
mtx_lock(&softc->state_lock);
|
||||
if (softc->flags & DETACHING) {
|
||||
ccb->ccb_h.status = CAM_REQ_ABORTED;
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (softc->atadev[tid] == NULL) {
|
||||
ccb->ccb_h.status = CAM_DEV_NOT_THERE;
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -494,7 +493,6 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
|
||||
printf("XPT_SCSI_IO received but already in progress?\n");
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
if (lid > 0) {
|
||||
@ -641,6 +639,7 @@ atapi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
mtx_unlock(&softc->state_lock);
|
||||
|
||||
ata_queue_request(request);
|
||||
mtx_lock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -657,21 +656,19 @@ action_oom:
|
||||
ata_free_request(request);
|
||||
if (hcb != NULL)
|
||||
free_hcb(hcb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
mtx_lock(&Giant);
|
||||
xpt_print_path(ccb_h->path);
|
||||
printf("out of memory, freezing queue.\n");
|
||||
softc->flags |= RESOURCE_SHORTAGE;
|
||||
xpt_freeze_simq(sim, /*count*/ 1);
|
||||
mtx_unlock(&Giant);
|
||||
ccb_h->status = CAM_REQUEUE_REQ;
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
|
||||
action_invalid:
|
||||
mtx_unlock(&softc->state_lock);
|
||||
ccb_h->status = CAM_REQ_INVALID;
|
||||
xpt_done(ccb);
|
||||
mtx_unlock(&softc->state_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -829,20 +826,22 @@ cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
|
||||
("Rescan succeeded\n"));
|
||||
}
|
||||
xpt_free_path(ccb->ccb_h.path);
|
||||
free(ccb, M_ATACAM);
|
||||
xpt_free_ccb(ccb);
|
||||
}
|
||||
|
||||
static void
|
||||
cam_rescan(struct cam_sim *sim)
|
||||
{
|
||||
struct cam_path *path;
|
||||
union ccb *ccb = malloc(sizeof(union ccb), M_ATACAM, M_WAITOK | M_ZERO);
|
||||
union ccb *ccb;
|
||||
|
||||
ccb = xpt_alloc_ccb_nowait();
|
||||
if (ccb == NULL)
|
||||
return;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
if (xpt_create_path(&path, xpt_periph, cam_sim_path(sim),
|
||||
CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
|
||||
mtx_unlock(&Giant);
|
||||
free(ccb, M_ATACAM);
|
||||
xpt_free_ccb(ccb);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -853,7 +852,6 @@ cam_rescan(struct cam_sim *sim)
|
||||
ccb->crcn.flags = CAM_FLAG_NONE;
|
||||
xpt_action(ccb);
|
||||
/* scan is in progress now */
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
|
||||
static struct atapi_hcb *
|
||||
@ -891,8 +889,6 @@ free_softc(struct atapi_xpt_softc *scp)
|
||||
TAILQ_FOREACH(hcb, &scp->pending_hcbs, chain) {
|
||||
free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR);
|
||||
}
|
||||
mtx_unlock(&scp->state_lock);
|
||||
mtx_lock(&Giant);
|
||||
if (scp->path != NULL) {
|
||||
setup_async_cb(scp, 0);
|
||||
xpt_free_path(scp->path);
|
||||
@ -908,7 +904,6 @@ free_softc(struct atapi_xpt_softc *scp)
|
||||
printf("Can't free %s SIM (still registered)\n",
|
||||
cam_sim_name(scp->sim));
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
mtx_destroy(&scp->state_lock);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user