Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/scsi/scsi_pass.c
Show First 20 Lines • Show All 1,776 Lines • ▼ Show 20 Lines | case CAMIOCOMMAND: | ||||
int ccb_malloced; | int ccb_malloced; | ||||
inccb = (union ccb *)addr; | inccb = (union ccb *)addr; | ||||
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) | #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) | ||||
if (inccb->ccb_h.func_code == XPT_SCSI_IO) | if (inccb->ccb_h.func_code == XPT_SCSI_IO) | ||||
inccb->csio.bio = NULL; | inccb->csio.bio = NULL; | ||||
#endif | #endif | ||||
if (inccb->ccb_h.flags & CAM_UNLOCKED) { | |||||
error = EINVAL; | |||||
break; | |||||
} | |||||
/* | /* | ||||
* Some CCB types, like scan bus and scan lun can only go | * Some CCB types, like scan bus and scan lun can only go | ||||
* through the transport layer device. | * through the transport layer device. | ||||
*/ | */ | ||||
if (inccb->ccb_h.func_code & XPT_FC_XPT_ONLY) { | if (inccb->ccb_h.func_code & XPT_FC_XPT_ONLY) { | ||||
xpt_print(periph->path, "CCB function code %#x is " | xpt_print(periph->path, "CCB function code %#x is " | ||||
"restricted to the XPT device\n", | "restricted to the XPT device\n", | ||||
inccb->ccb_h.func_code); | inccb->ccb_h.func_code); | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | #if 0 | ||||
xpt_print(periph->path, "Copying user CCB %p to " | xpt_print(periph->path, "Copying user CCB %p to " | ||||
"kernel address %p\n", *user_ccb, ccb); | "kernel address %p\n", *user_ccb, ccb); | ||||
#endif | #endif | ||||
error = copyin(*user_ccb, ccb, sizeof(*ccb)); | error = copyin(*user_ccb, ccb, sizeof(*ccb)); | ||||
if (error != 0) { | if (error != 0) { | ||||
xpt_print(periph->path, "Copy of user CCB %p to " | xpt_print(periph->path, "Copy of user CCB %p to " | ||||
"kernel address %p failed with error %d\n", | "kernel address %p failed with error %d\n", | ||||
*user_ccb, ccb, error); | *user_ccb, ccb, error); | ||||
uma_zfree(softc->pass_zone, io_req); | goto camioqueue_error; | ||||
cam_periph_lock(periph); | |||||
break; | |||||
} | } | ||||
#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) | #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) | ||||
if (ccb->ccb_h.func_code == XPT_SCSI_IO) | if (ccb->ccb_h.func_code == XPT_SCSI_IO) | ||||
ccb->csio.bio = NULL; | ccb->csio.bio = NULL; | ||||
#endif | #endif | ||||
if (ccb->ccb_h.flags & CAM_UNLOCKED) { | |||||
error = EINVAL; | |||||
goto camioqueue_error; | |||||
} | |||||
if (ccb->ccb_h.flags & CAM_CDB_POINTER) { | if (ccb->ccb_h.flags & CAM_CDB_POINTER) { | ||||
if (ccb->csio.cdb_len > IOCDBLEN) { | if (ccb->csio.cdb_len > IOCDBLEN) { | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | goto camioqueue_error; | ||||
} | } | ||||
error = copyin(ccb->csio.cdb_io.cdb_ptr, | error = copyin(ccb->csio.cdb_io.cdb_ptr, | ||||
ccb->csio.cdb_io.cdb_bytes, ccb->csio.cdb_len); | ccb->csio.cdb_io.cdb_bytes, ccb->csio.cdb_len); | ||||
if (error) | if (error != 0) | ||||
break; | goto camioqueue_error; | ||||
ccb->ccb_h.flags &= ~CAM_CDB_POINTER; | ccb->ccb_h.flags &= ~CAM_CDB_POINTER; | ||||
} | } | ||||
/* | /* | ||||
* Some CCB types, like scan bus and scan lun can only go | * Some CCB types, like scan bus and scan lun can only go | ||||
* through the transport layer device. | * through the transport layer device. | ||||
*/ | */ | ||||
if (ccb->ccb_h.func_code & XPT_FC_XPT_ONLY) { | if (ccb->ccb_h.func_code & XPT_FC_XPT_ONLY) { | ||||
xpt_print(periph->path, "CCB function code %#x is " | xpt_print(periph->path, "CCB function code %#x is " | ||||
"restricted to the XPT device\n", | "restricted to the XPT device\n", | ||||
ccb->ccb_h.func_code); | ccb->ccb_h.func_code); | ||||
uma_zfree(softc->pass_zone, io_req); | |||||
cam_periph_lock(periph); | |||||
error = ENODEV; | error = ENODEV; | ||||
break; | goto camioqueue_error; | ||||
} | } | ||||
/* | /* | ||||
* Save the user's CCB pointer as well as his linked list | * Save the user's CCB pointer as well as his linked list | ||||
* pointers and peripheral private area so that we can | * pointers and peripheral private area so that we can | ||||
* restore these later. | * restore these later. | ||||
*/ | */ | ||||
io_req->user_ccb_ptr = *user_ccb; | io_req->user_ccb_ptr = *user_ccb; | ||||
Show All 29 Lines | #endif | ||||
/* | /* | ||||
* If this function code has memory that can be mapped in | * If this function code has memory that can be mapped in | ||||
* or out, we need to call passmemsetup(). | * or out, we need to call passmemsetup(). | ||||
*/ | */ | ||||
if ((fc == XPT_SCSI_IO) || (fc == XPT_ATA_IO) | if ((fc == XPT_SCSI_IO) || (fc == XPT_ATA_IO) | ||||
|| (fc == XPT_SMP_IO) || (fc == XPT_DEV_MATCH) | || (fc == XPT_SMP_IO) || (fc == XPT_DEV_MATCH) | ||||
|| (fc == XPT_DEV_ADVINFO)) { | || (fc == XPT_DEV_ADVINFO)) { | ||||
error = passmemsetup(periph, io_req); | error = passmemsetup(periph, io_req); | ||||
if (error != 0) { | if (error != 0) | ||||
uma_zfree(softc->pass_zone, io_req); | goto camioqueue_error; | ||||
cam_periph_lock(periph); | |||||
break; | |||||
} | |||||
} else | } else | ||||
io_req->mapinfo.num_bufs_used = 0; | io_req->mapinfo.num_bufs_used = 0; | ||||
cam_periph_lock(periph); | cam_periph_lock(periph); | ||||
/* | /* | ||||
* Everything goes on the incoming queue initially. | * Everything goes on the incoming queue initially. | ||||
*/ | */ | ||||
Show All 27 Lines | #endif | ||||
* If this is not a queued CCB (i.e. it is an immediate CCB), | * If this is not a queued CCB (i.e. it is an immediate CCB), | ||||
* then it is already done. We need to put it on the done | * then it is already done. We need to put it on the done | ||||
* queue for the user to fetch. | * queue for the user to fetch. | ||||
*/ | */ | ||||
if ((fc & XPT_FC_QUEUED) == 0) { | if ((fc & XPT_FC_QUEUED) == 0) { | ||||
TAILQ_REMOVE(&softc->active_queue, io_req, links); | TAILQ_REMOVE(&softc->active_queue, io_req, links); | ||||
TAILQ_INSERT_TAIL(&softc->done_queue, io_req, links); | TAILQ_INSERT_TAIL(&softc->done_queue, io_req, links); | ||||
} | } | ||||
break; | |||||
camioqueue_error: | |||||
uma_zfree(softc->pass_zone, io_req); | |||||
cam_periph_lock(periph); | |||||
break; | break; | ||||
} | } | ||||
case CAMIOGET: | case CAMIOGET: | ||||
{ | { | ||||
union ccb **user_ccb; | union ccb **user_ccb; | ||||
struct pass_io_req *io_req; | struct pass_io_req *io_req; | ||||
int old_error; | int old_error; | ||||
▲ Show 20 Lines • Show All 238 Lines • Show Last 20 Lines |