39#include <sys/kernel.h>
42#include <sys/malloc.h>
44#include <sys/ioccom.h>
47#include <sys/devicestat.h>
82#define ccb_type ppriv_field0
83#define ccb_rdwr ppriv_ptr1
121static void sgasync(
void *callback_arg, uint32_t code,
127 uint32_t sense_flags);
129 u_short *hoststat, u_short *drvstat);
136 TAILQ_HEAD_INITIALIZER(
sgdriver.units), 0
141 .d_version = D_VERSION,
142 .d_flags = D_TRACKCLOSE,
165 printf(
"sg: Failed to attach master async callbac "
166 "due to status 0x%x!\n", status);
183 KASSERT(softc->
open_count >= 0, (
"Negative open count %d",
229 destroy_dev_sched_cb(softc->dev,
sgdevgonecb, periph);
248 free(softc, M_DEVBUF);
283 printf(
"sgasync: Unable to attach new device "
284 "due to status %#x: %s\n", status, entry ?
301 struct make_dev_args args;
306 printf(
"sgregister: no getdev CCB, can't register device\n");
310 softc = malloc(
sizeof(*softc), M_DEVBUF, M_ZERO | M_NOWAIT);
312 printf(
"sgregister: Unable to allocate softc\n");
320 TAILQ_INIT(&softc->rdwr_done);
321 periph->
softc = softc;
326 softc->
maxio = DFLTPHYS;
327 else if (cpi.
maxio > maxphys)
328 softc->
maxio = maxphys;
341 | (no_tags ? DEVSTAT_NO_ORDERED_TAGS : 0),
345 DEVSTAT_PRIORITY_PASS);
354 "registration!\n", __func__);
360 make_dev_args_init(&args);
363 args.mda_uid = UID_ROOT;
364 args.mda_gid = GID_OPERATOR;
365 args.mda_mode = 0600;
366 args.mda_si_drv1 = periph;
367 error = make_dev_s(&args, &softc->dev,
"%s%d",
375 (void)make_dev_alias(softc->dev,
"sg%c",
378 (void)make_dev_alias(softc->dev,
"sg%c%c",
403 csio = &done_ccb->
csio;
404 switch (csio->
ccb_h.ccb_type) {
415 DEVSTAT_WRITE : DEVSTAT_READ,
418 rdwr = done_ccb->
ccb_h.ccb_rdwr;
424 panic(
"unknown sg CCB type");
429sgopen(
struct cdev *dev,
int flags,
int fmt,
struct thread *td)
442 error = securelevel_gt(td->td_ucred, 1);
465sgclose(
struct cdev *dev,
int flag,
int fmt,
struct thread *td)
498sgioctl(
struct cdev *dev, u_long cmd, caddr_t arg,
int flag,
struct thread *td)
516 int *version = (
int *)arg;
523 u_int user_timeout = *(u_int *)arg;
525 softc->sg_user_timeout = user_timeout;
533 td->td_retval[0] = softc->sg_user_timeout;
602 && (req->
sbp != NULL)) {
613 int *size = (
int *)arg;
626 id->scsi_type = softc->pd_type;
627 id->h_cmd_per_lun = 1;
628 id->d_queue_depth = 1;
636 int *size = (
int *)arg;
661 printf(
"sgioctl: rejecting cmd 0x%lx\n", cmd);
672sgwrite(
struct cdev *dev,
struct uio *uio,
int ioflag)
682 int error = 0, cdb_len, buf_len, dir;
684 periph = dev->si_drv1;
685 rdwr = malloc(
sizeof(*rdwr), M_DEVBUF, M_WAITOK | M_ZERO);
689 if (uio->uio_resid <
sizeof(*
hdr)) {
693 error = uiomove(
hdr,
sizeof(*
hdr), uio);
698 if (
hdr->reply_len < 0) {
715 if (uio->uio_resid < 1)
717 error = uiomove(&cdb_cmd, 1, uio);
720 if (
hdr->twelve_byte)
737 buf_len = uio->uio_resid;
739 buf = malloc(buf_len, M_DEVBUF, M_WAITOK | M_ZERO);
740 error = uiomove(buf, buf_len, uio);
744 }
else if (
hdr->reply_len != 0) {
745 buf = malloc(
hdr->reply_len, M_DEVBUF, M_WAITOK | M_ZERO);
746 buf_len =
hdr->reply_len;
773 rdwr->buf_len = buf_len;
774 rdwr->tag =
hdr->pack_id;
779 TAILQ_INSERT_TAIL(&sc->rdwr_done, rdwr, rdwr_link);
789 free(rdwr, M_DEVBUF);
794sgread(
struct cdev *dev,
struct uio *uio,
int ioflag)
801 u_short hstat, dstat;
802 int error, pack_len, reply_len, pack_id;
804 periph = dev->si_drv1;
809 uio->uio_rw = UIO_WRITE;
810 if ((error = uiomove(&pack_len, 4, uio)) != 0)
812 if ((error = uiomove(&reply_len, 4, uio)) != 0)
814 if ((error = uiomove(&pack_id, 4, uio)) != 0)
816 uio->uio_rw = UIO_READ;
821 TAILQ_FOREACH(rdwr, &sc->rdwr_done, rdwr_link) {
822 if (rdwr->tag == pack_id)
830 TAILQ_REMOVE(&sc->rdwr_done, rdwr, rdwr_link);
834 csio = &rdwr->ccb->csio;
836 hdr->host_status = hstat;
837 hdr->driver_status = dstat;
870 error = uiomove(&
hdr->result,
sizeof(*
hdr) -
871 offsetof(
struct sg_header, result), uio);
872 if ((error == 0) && (
hdr->result == 0))
873 error = uiomove(rdwr->buf, rdwr->buf_len, uio);
878 free(rdwr->buf, M_DEVBUF);
879 free(rdwr, M_DEVBUF);
890 softc = periph->
softc;
891 bzero(&mapinfo,
sizeof(mapinfo));
924 softc = periph->
softc;
1001 int len[] = {6, 10, 10, 12, 12, 12, 10, 10};
1004 group = (cmd >> 5) & 0x7;
1005 return (len[group]);
const struct cam_status_entry * cam_fetch_status_entry(cam_status status)
#define CAM_PRIORITY_NORMAL
static __BEGIN_DECLS __inline void cam_fill_csio(struct ccb_scsiio *csio, u_int32_t retries, void(*cbfcnp)(struct cam_periph *, union ccb *), u_int32_t flags, u_int8_t tag_action, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int8_t cdb_len, u_int32_t timeout)
#define XPORT_DEVSTAT_TYPE(t)
void cam_periph_release_locked(struct cam_periph *periph)
void cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
int cam_periph_acquire(struct cam_periph *periph)
void cam_periph_async(struct cam_periph *periph, u_int32_t code, struct cam_path *path, void *arg)
void cam_periph_release(struct cam_periph *periph)
int cam_periph_runccb(union ccb *ccb, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags), cam_flags camflags, u_int32_t sense_flags, struct devstat *ds)
int cam_periph_error(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags)
int cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo, u_int maxmap)
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, periph_oninv_t *periph_oninvalidate, periph_dtor_t *periph_dtor, periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *path, ac_callback_t *ac_callback, ac_code code, void *arg)
cam_status periph_ctor_t(struct cam_periph *periph, void *arg)
void periph_oninv_t(struct cam_periph *periph)
#define cam_periph_lock(periph)
union ccb * cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
#define cam_periph_unlock(periph)
static __inline struct mtx * cam_periph_mtx(struct cam_periph *periph)
void periph_dtor_t(struct cam_periph *periph)
#define cam_periph_sleep(periph, chan, priority, wmesg, timo)
void() periph_init_t(void)
TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr)
static __inline u_int32_t cam_sim_path(const struct cam_sim *sim)
union ccb * xpt_alloc_ccb(void)
void xpt_print(struct cam_path *path, const char *fmt,...)
path_id_t xpt_path_path_id(struct cam_path *path)
void xpt_announce_periph(struct cam_periph *periph, char *announce_string)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
void xpt_action(union ccb *start_ccb)
cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path)
lun_id_t xpt_path_lun_id(struct cam_path *path)
struct cam_sim * xpt_path_sim(struct cam_path *path)
void xpt_release_ccb(union ccb *free_ccb)
target_id_t xpt_path_target_id(struct cam_path *path)
void xpt_free_ccb(union ccb *free_ccb)
static void xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path)
void scsi_sense_print(struct ccb_scsiio *csio)
#define SID_TYPE(inq_data)
static void sg_scsiio_status(struct ccb_scsiio *csio, u_short *hoststat, u_short *drvstat)
static int sgsendccb(struct cam_periph *periph, union ccb *ccb)
static int scsi_group_len(u_char cmd)
static struct periph_driver sgdriver
static struct cdevsw sg_cdevsw
PERIPHDRIVER_DECLARE(sg, sgdriver)
static int sgsendrdwr(struct cam_periph *periph, union ccb *ccb)
static void sgasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
static void sgdevgonecb(void *arg)
static void sgdone(struct cam_periph *periph, union ccb *done_ccb)
static periph_dtor_t sgcleanup
static periph_ctor_t sgregister
static periph_init_t sginit
static periph_oninv_t sgoninvalidate
static int sgerror(union ccb *ccb, uint32_t cam_flags, uint32_t sense_flags)
#define SG_SET_FORCE_LOW_DMA
#define SG_GET_RESERVED_SIZE
#define SG_SET_RESERVED_SIZE
#define SG_DXFER_FROM_DEV
#define SG_GET_VERSION_NUM
#define SG_GET_SG_TABLESIZE
#define SG_DXFER_TO_FROM_DEV
#define SG_GET_NUM_WAITING
#define SG_SET_FORCE_PACK_ID
#define SG_GET_KEEP_ORPHAN
#define SG_DEFAULT_TIMEOUT
#define SG_GET_ACCESS_COUNT
#define SG_GET_REQUEST_TABLE
#define SG_SET_KEEP_ORPHAN
struct scsi_inquiry_data inq_data
struct scsi_sense_data sense_data
struct devstat * device_stats
u_int8_t cdb_bytes[IOCDBLEN]