Add a per controller IOCTL interface.

This commit is contained in:
Matthew N. Dodd 2004-01-15 06:37:52 +00:00
parent b7279e13a8
commit a85ce5b61f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=124540
3 changed files with 142 additions and 1 deletions

View File

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/stat.h>
#include <sys/bio.h>
#include <sys/bus.h>
@ -54,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ida/idareg.h>
#include <dev/ida/idavar.h>
#include <dev/ida/idaio.h>
/* prototypes */
static void ida_alloc_qcb(struct ida_softc *ida);
@ -62,6 +64,12 @@ static void ida_start(struct ida_softc *ida);
static void ida_done(struct ida_softc *ida, struct ida_qcb *qcb);
static int ida_wait(struct ida_softc *ida, struct ida_qcb *qcb);
static d_ioctl_t ida_ioctl;
static struct cdevsw ida_cdevsw = {
.d_ioctl = ida_ioctl,
.d_name = "ida",
};
void
ida_free(struct ida_softc *ida)
{
@ -268,6 +276,11 @@ ida_attach(struct ida_softc *ida)
}
}
ida->ida_dev_t = make_dev(&ida_cdevsw, ida->unit,
UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
"ida%d", ida->unit);
ida->ida_dev_t->si_drv1 = ida;
ida->num_drives = 0;
for (i = 0; i < cinfo.num_drvs; i++)
device_add_child(ida->dev, /*"idad"*/NULL, -1);
@ -297,7 +310,7 @@ ida_detach(device_t dev)
* iterate over our "child devices"?
*/
destroy_dev(ida->ida_dev_t);
ida_free(ida);
return (error);
}
@ -548,3 +561,107 @@ ida_done(struct ida_softc *ida, struct ida_qcb *qcb)
SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle);
ida_construct_qcb(ida);
}
/*
* IOCTL stuff follows.
*/
struct cmd_info {
int cmd;
int len;
int flags;
};
static struct cmd_info *ida_cmd_lookup(int);
static int
ida_ioctl (dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td)
{
struct ida_softc *sc;
struct ida_user_command *uc;
struct cmd_info *ci;
int len;
int flags;
int error;
int data;
void *daddr;
sc = (struct ida_softc *)dev->si_drv1;
uc = (struct ida_user_command *)addr;
error = 0;
switch (cmd) {
case IDAIO_COMMAND:
ci = ida_cmd_lookup(uc->command);
if (ci == NULL) {
error = EINVAL;
break;
}
len = ci->len;
flags = ci->flags;
if (len)
daddr = &uc->d.buf;
else {
daddr = &data;
len = sizeof(data);
}
error = ida_command(sc, uc->command, daddr, len,
uc->drive, uc->blkno, flags);
break;
default:
error = ENOIOCTL;
break;
}
return (error);
}
static struct cmd_info ci_list[] = {
{ CMD_GET_LOG_DRV_INFO,
sizeof(struct ida_drive_info), DMA_DATA_IN },
{ CMD_GET_CTRL_INFO,
sizeof(struct ida_controller_info), DMA_DATA_IN },
{ CMD_SENSE_DRV_STATUS,
sizeof(struct ida_drive_status), DMA_DATA_IN },
{ CMD_START_RECOVERY, 0, 0 },
{ CMD_GET_PHYS_DRV_INFO,
sizeof(struct ida_phys_drv_info), DMA_DATA_TRANSFER },
{ CMD_BLINK_DRV_LEDS,
sizeof(struct ida_blink_drv_leds), DMA_DATA_OUT },
{ CMD_SENSE_DRV_LEDS,
sizeof(struct ida_blink_drv_leds), DMA_DATA_IN },
{ CMD_GET_LOG_DRV_EXT,
sizeof(struct ida_drive_info_ext), DMA_DATA_IN },
{ CMD_RESET_CTRL, 0, 0 },
{ CMD_GET_CONFIG, 0, 0 },
{ CMD_SET_CONFIG, 0, 0 },
{ CMD_LABEL_LOG_DRV,
sizeof(struct ida_label_logical), DMA_DATA_OUT },
{ CMD_SET_SURFACE_DELAY, 0, 0 },
{ CMD_SENSE_BUS_PARAMS, 0, 0 },
{ CMD_SENSE_SUBSYS_INFO, 0, 0 },
{ CMD_SENSE_SURFACE_ATS, 0, 0 },
{ CMD_PASSTHROUGH, 0, 0 },
{ CMD_RESET_SCSI_DEV, 0, 0 },
{ CMD_PAUSE_BG_ACT, 0, 0 },
{ CMD_RESUME_BG_ACT, 0, 0 },
{ CMD_START_FIRMWARE, 0, 0 },
{ CMD_SENSE_DRV_ERR_LOG, 0, 0 },
{ CMD_START_CPM, 0, 0 },
{ CMD_SENSE_CP, 0, 0 },
{ CMD_STOP_CPM, 0, 0 },
{ CMD_FLUSH_CACHE, 0, 0 },
{ CMD_ACCEPT_MEDIA_EXCH, 0, 0 },
{ 0, 0, 0 }
};
static struct cmd_info *
ida_cmd_lookup (int command)
{
struct cmd_info *ci;
ci = ci_list;
while (ci->cmd) {
if (ci->cmd == command)
return (ci);
ci++;
}
return (NULL);
}

23
sys/dev/ida/idaio.h Normal file
View File

@ -0,0 +1,23 @@
/*
* $FreeBSD$
*/
#include <sys/ioccom.h>
struct ida_user_command {
int command;
int drive;
u_int32_t blkno;
union {
struct ida_drive_info di;
struct ida_drive_info_ext die;
struct ida_controller_info ci;
struct ida_drive_status ds;
struct ida_phys_drv_info pdi;
struct ida_blink_drv_leds bdl;
struct ida_label_logical ll;
u_int8_t buf;
} d;
};
#define IDAIO_COMMAND _IOWR('I', 100, struct ida_user_command)

View File

@ -126,6 +126,7 @@ struct ida_access {
struct ida_softc {
device_t dev;
int unit;
dev_t ida_dev_t;
int regs_res_type;
int regs_res_id;