37#include <sys/kernel.h>
40#include <sys/module.h>
42#include <sys/condvar.h>
43#include <sys/malloc.h>
46#include <sys/sysctl.h>
93static int cfi_ioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int flag,
99 .d_version = D_VERSION,
121 memset(isoftc, 0,
sizeof(*isoftc));
122 TAILQ_INIT(&isoftc->ports);
124 cfi = malloc(
sizeof(*cfi), M_CTL, M_WAITOK | M_ZERO);
136 printf(
"%s: ioctl port registration failed\n", __func__);
141 TAILQ_INSERT_TAIL(&isoftc->ports, cfi, link);
153 TAILQ_FOREACH_SAFE(cfi, &isoftc->ports, link, temp) {
158 printf(
"%s: ctl_frontend_deregister() failed\n",
163 TAILQ_REMOVE(&isoftc->ports, cfi, link);
176 struct make_dev_args args;
181 val = dnvlist_get_string(req->
args_nvl,
"pp", NULL);
183 pp = strtol(val, NULL, 10);
185 val = dnvlist_get_string(req->
args_nvl,
"vp", NULL);
187 vp = strtol(val, NULL, 10);
191 TAILQ_FOREACH(cfi, &isoftc->ports, link) {
192 if (pp == cfi->port.physical_port &&
193 vp == cfi->port.virtual_port) {
196 "port %d already exists", pp);
203 TAILQ_FOREACH(cfi, &isoftc->ports, link) {
204 pp = MAX(pp, cfi->port.physical_port);
210 cfi = malloc(
sizeof(*cfi), M_CTL, M_WAITOK | M_ZERO);
226 "ctl_port_register() failed with error %d", retval);
235 make_dev_args_init(&args);
237 args.mda_uid = UID_ROOT;
238 args.mda_gid = GID_OPERATOR;
239 args.mda_mode = 0600;
240 args.mda_si_drv1 = NULL;
241 args.mda_si_drv2 = cfi;
243 retval = make_dev_s(&args, &cfi->dev,
"cam/ctl%d.%d", pp, vp);
247 "make_dev_s() failed with error %d", retval);
255 TAILQ_INSERT_TAIL(&isoftc->ports, cfi, link);
266 val = dnvlist_get_string(req->
args_nvl,
"port_id", NULL);
268 port_id = strtol(val, NULL, 10);
273 "port_id not provided");
277 TAILQ_FOREACH(cfi, &isoftc->ports, link) {
278 if (cfi->port.targ_port == port_id)
285 "cannot find port %d", port_id);
290 if (cfi->port.physical_port == 0 && cfi->port.virtual_port == 0) {
293 "cannot destroy default ioctl port");
300 TAILQ_REMOVE(&isoftc->ports, cfi, link);
301 destroy_dev(cfi->dev);
307cfi_ioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int flag,
324 "Unsupported request type %d", req->
reqtype);
340 int ext_sglen, ext_sg_entries, kern_sg_entries;
341 int ext_sg_start, ext_offset;
343 int kern_watermark, ext_watermark;
344 int ext_sglist_malloced;
353 ext_sglist_malloced = 0;
367 ext_sglist = (
struct ctl_sg_entry *)malloc(ext_sglen, M_CTL,
369 ext_sglist_malloced = 1;
370 if (copyin(ctsio->
ext_data_ptr, ext_sglist, ext_sglen) != 0) {
375 ext_sg_start = ext_sg_entries;
378 for (i = 0; i < ext_sg_entries; i++) {
379 if ((len_seen + ext_sglist[i].
len) >=
385 len_seen += ext_sglist[i].
len;
388 ext_sglist = &ext_entry;
389 ext_sglist_malloced = 0;
401 kern_sglist = &kern_entry;
408 ext_watermark = ext_offset;
409 for (i = ext_sg_start, j = 0;
410 i < ext_sg_entries && j < kern_sg_entries;) {
411 uint8_t *ext_ptr, *kern_ptr;
413 len_to_copy = MIN(ext_sglist[i].
len - ext_watermark,
414 kern_sglist[j].
len - kern_watermark);
416 ext_ptr = (uint8_t *)ext_sglist[i].
addr;
417 ext_ptr = ext_ptr + ext_watermark;
422 panic(
"need to implement bus address support");
424 kern_ptr = bus_to_virt(kern_sglist[j].
addr);
427 kern_ptr = (uint8_t *)kern_sglist[j].
addr;
428 kern_ptr = kern_ptr + kern_watermark;
433 "bytes to user\n", len_to_copy));
435 "to %p\n", kern_ptr, ext_ptr));
436 if (copyout(kern_ptr, ext_ptr, len_to_copy) != 0) {
442 "bytes from user\n", len_to_copy));
444 "to %p\n", ext_ptr, kern_ptr));
445 if (copyin(ext_ptr, kern_ptr, len_to_copy)!= 0){
454 ext_watermark += len_to_copy;
455 if (ext_sglist[i].
len == ext_watermark) {
460 kern_watermark += len_to_copy;
461 if (kern_sglist[j].
len == kern_watermark) {
468 "kern_sg_entries: %d\n", ext_sg_entries,
475 if (ext_sglist_malloced != 0)
476 free(ext_sglist, M_CTL);
491 cv_broadcast(¶ms->
sem);
505 cv_broadcast(¶ms->
sem);
516 bzero(¶ms,
sizeof(params));
517 mtx_init(¶ms.
ioctl_mtx,
"ctliocmtx", NULL, MTX_DEF);
518 cv_init(¶ms.
sem,
"ctlioccv");
520 last_state = params.
state;
539 if (params.
state == last_state) {
543 last_state = params.
state;
545 switch (params.
state) {
584 cv_destroy(¶ms.
sem);
595 void *pool_tmp, *sc_tmp;
601 cfi = dev->si_drv2 == NULL
620 memcpy(io, (
void *)addr,
sizeof(*io));
623 TAILQ_INIT(&io->
io_hdr.blocked_queue);
641 memcpy((
void *)addr, io,
sizeof(*io));
TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr)
void ctl_free_io(union ctl_io *io)
void ctl_datamove_done(union ctl_io *io, bool samethr)
int ctl_run(union ctl_io *io)
union ctl_io * ctl_alloc_io(void *pool_ref)
#define CTL_RETVAL_COMPLETE
#define CTL_DEBUG_PRINT(X)
int ctl_port_deregister(struct ctl_port *port)
void ctl_port_offline(struct ctl_port *port)
void ctl_port_online(struct ctl_port *port)
int ctl_port_register(struct ctl_port *port)
static int cfi_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
static int cfi_shutdown(void)
static struct ctl_frontend cfi_frontend
static void cfi_ioctl_port_remove(struct ctl_req *req)
static struct cdevsw cfi_cdevsw
static void cfi_datamove(union ctl_io *io)
static struct cfi_softc cfi_softc
static int cfi_submit_wait(union ctl_io *io)
static void cfi_done(union ctl_io *io)
static int cfi_init(void)
CTL_FRONTEND_DECLARE(ctlioctl, cfi_frontend)
static void cfi_ioctl_port_create(struct ctl_req *req)
int ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
static int ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
#define CTL_PRIV_FRONTEND
char name[CTL_DRIVER_NAME_LEN]
union ctl_priv ctl_private[CTL_NUM_PRIV]
struct ctl_frontend * frontend
void(* fe_datamove)(union ctl_io *io)
void(* fe_done)(union ctl_io *io)
char error_str[CTL_ERROR_STR_LEN]