From 6667b30d15254872b686d582b2430e2e9098aacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Mon, 16 May 2005 13:07:27 +0000 Subject: [PATCH] Change the way ioctls are issue to ATA. The most prominent part is that its now possible to issue ata_requests directly to say acd0, instead of going through the cumbersome /dev/ata device. --- sbin/atacontrol/atacontrol.c | 414 +++++++++++---------- sys/dev/ata/ata-all.c | 371 +++++++++---------- sys/dev/ata/ata-all.h | 145 ++++---- sys/dev/ata/ata-chipset.c | 98 ++--- sys/dev/ata/ata-disk.c | 8 + sys/dev/ata/ata-lowlevel.c | 79 ++-- sys/dev/ata/ata-pci.h | 10 +- sys/dev/ata/ata-raid.c | 85 ++--- sys/dev/ata/atapi-cam.c | 2 +- sys/dev/ata/atapi-cd.c | 3 +- sys/dev/ata/atapi-fd.c | 8 + sys/dev/ata/atapi-tape.c | 16 +- sys/sys/ata.h | 689 +++++++++++++++++------------------ 13 files changed, 962 insertions(+), 966 deletions(-) diff --git a/sbin/atacontrol/atacontrol.c b/sbin/atacontrol/atacontrol.c index 4f1973a75abb..4a8349fc8f5e 100644 --- a/sbin/atacontrol/atacontrol.c +++ b/sbin/atacontrol/atacontrol.c @@ -46,7 +46,7 @@ void usage(void); int version(int ver); void param_print(struct ata_params *parm); void cap_print(struct ata_params *parm); -int ata_cap_print(int fd, int channel, int device); +int ata_cap_print(int fd); int info_print(int fd, int channel, int prchan); const char * @@ -95,7 +95,21 @@ str2mode(char *str) void usage() { - fprintf(stderr, "usage: atacontrol channel [args]\n"); + fprintf(stderr, + "usage: atacontrol args:\n" + " atacontrol list\n" + " atacontrol info channel\n" + " atacontrol attach channel\n" + " atacontrol detach channel\n" + " atacontrol reinit channel\n" + " atacontrol create type [interleave] disk0 ... diskN\n" + " atacontrol delete channel\n" + " atacontrol addspare array disk\n" + " atacontrol rebuild array\n" + " atacontrol status array\n" + " atacontrol mode device [mode]\n" + " atacontrol cap device\n" + ); exit(EX_USAGE); } @@ -176,7 +190,7 @@ cap_print(struct ata_params *parm) parm->capabilities1 & ATA_SUPPORT_OVERLAP ? " " : " not "); printf("\nFeature " - "Support Enable Value Vendor\n"); + "Support Enable Value Vendor\n"); printf("write cache %s %s\n", parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no", @@ -187,7 +201,8 @@ cap_print(struct ata_params *parm) parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); if (parm->satacapabilities && parm->satacapabilities != 0xffff) { - printf("Native Command Queuing (NCQ) %s %s %d/0x%02X\n", + printf("Native Command Queuing (NCQ) %s %s" + " %d/0x%02X\n", parm->satacapabilities & ATA_SUPPORT_NCQ ? "yes" : "no", " -", (parm->satacapabilities & ATA_SUPPORT_NCQ) ? @@ -232,57 +247,39 @@ cap_print(struct ata_params *parm) } int -ata_cap_print(int fd, int channel, int device) +ata_cap_print(int fd) { - struct ata_cmd iocmd; + struct ata_params params; - if (device < 0 || device > 1) - return ENXIO; - - bzero(&iocmd, sizeof(struct ata_cmd)); - - iocmd.channel = channel; - iocmd.device = device; - iocmd.cmd = ATAGPARM; - - if (ioctl(fd, IOCATA, &iocmd) < 0) + if (ioctl(fd, IOCATAGPARM, ¶ms) < 0) return errno; - - printf("ATA channel %d, %s", channel, device==0 ? "Master" : "Slave"); - - if (iocmd.u.param.type[device]) { - printf(", device %s:\n", iocmd.u.param.name[device]); - cap_print(&iocmd.u.param.params[device]); - } - else - printf(": no device present\n"); + cap_print(¶ms); return 0; } int info_print(int fd, int channel, int prchan) { - struct ata_cmd iocmd; + struct ata_ioc_devices devices; - bzero(&iocmd, sizeof(struct ata_cmd)); - iocmd.channel = channel; - iocmd.device = -1; - iocmd.cmd = ATAGPARM; - if (ioctl(fd, IOCATA, &iocmd) < 0) + devices.channel = channel; + + if (ioctl(fd, IOCATADEVICES, &devices) < 0) return errno; + if (prchan) printf("ATA channel %d:\n", channel); printf("%sMaster: ", prchan ? " " : ""); - if (iocmd.u.param.type[0]) { - printf("%4.4s ", iocmd.u.param.name[0]); - param_print(&iocmd.u.param.params[0]); + if (*devices.name[0]) { + printf("%4.4s ", devices.name[0]); + param_print(&devices.params[0]); } else printf(" no device present\n"); printf("%sSlave: ", prchan ? " " : ""); - if (iocmd.u.param.type[1]) { - printf("%4.4s ", iocmd.u.param.name[1]); - param_print(&iocmd.u.param.params[1]); + if (*devices.name[1]) { + printf("%4.4s ", devices.name[1]); + param_print(&devices.params[1]); } else printf(" no device present\n"); @@ -292,118 +289,158 @@ info_print(int fd, int channel, int prchan) int main(int argc, char **argv) { - struct ata_cmd iocmd; - int fd, maxunit, unit; - - if ((fd = open("/dev/ata", O_RDWR)) < 0) - err(1, "control device not found"); + int fd; if (argc < 2) usage(); - bzero(&iocmd, sizeof(struct ata_cmd)); + if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 4)) { + int disk, mode; + char device[64]; - if (argc > 2 && strcmp(argv[1], "create")) { - int chan; - - if (!strcmp(argv[1], "addspare") || - !strcmp(argv[1], "delete") || - !strcmp(argv[1], "rebuild") || - !strcmp(argv[1], "status")) { - if (!(sscanf(argv[2], "%d", &chan) == 1 || - sscanf(argv[2], "ar%d", &chan) == 1)) { - fprintf(stderr, "atacontrol: Invalid RAID device\n"); - exit(EX_USAGE); - } + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); } - else { - if (!(sscanf(argv[2], "%d", &chan) == 1 || - sscanf(argv[2], "ata%d", &chan) == 1)) { - fprintf(stderr, "atacontrol: Invalid ATA channel\n"); - exit(EX_USAGE); - } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDWR)) < 0) + err(1, "device not found"); + if (argc == 4) { + mode = str2mode(argv[3]); + if (ioctl(fd, IOCATASMODE, &mode) < 0) + warn("ioctl(IOCATASMODE)"); } - iocmd.channel = chan; + if (argc == 3 || argc == 4) { + if (ioctl(fd, IOCATAGMODE, &mode) < 0) + err(1, "ioctl(IOCATAGMODE)"); + printf("current mode = %s\n", mode2str(mode)); + } + exit(EX_OK); } + if (!strcmp(argv[1], "cap") && argc == 3) { + int disk; + char device[64]; + + if (!(sscanf(argv[2], "ad%d", &disk) == 1 || + sscanf(argv[2], "acd%d", &disk) == 1 || + sscanf(argv[2], "afd%d", &disk) == 1 || + sscanf(argv[2], "ast%d", &disk) == 1)) { + fprintf(stderr, "atacontrol: Invalid device %s\n", + argv[2]); + exit(EX_USAGE); + } + sprintf(device, "/dev/%s", argv[2]); + if ((fd = open(device, O_RDWR)) < 0) + err(1, "device not found"); + ata_cap_print(fd); + exit(EX_OK); + } + + if ((fd = open("/dev/ata", O_RDWR)) < 0) + err(1, "control device not found"); if (!strcmp(argv[1], "list") && argc == 2) { - iocmd.cmd = ATAGMAXCHANNEL; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATAGMAXCHANNEL)"); - maxunit = iocmd.u.maxchan; - for (unit = 0; unit < maxunit; unit++) - info_print(fd, unit, 1); - } - else if (!strcmp(argv[1], "info") && argc == 3) { - info_print(fd, iocmd.channel, 0); - } - else if (!strcmp(argv[1], "cap") && argc == 4) { - ata_cap_print(fd, iocmd.channel, atoi(argv[3])); - } - else if (!strcmp(argv[1], "enclosure") && argc == 4) { - iocmd.device = atoi(argv[3]); - iocmd.cmd = ATAENCSTAT; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATAENCSTAT)"); - printf("fan RPM: %d temp: %.1f 5V: %.2f 12V: %.2f\n", - iocmd.u.enclosure.fan, - (double)iocmd.u.enclosure.temp / 10, - (double)iocmd.u.enclosure.v05 / 1000, - (double)iocmd.u.enclosure.v12 / 1000); - } - else if (!strcmp(argv[1], "detach") && argc == 3) { - iocmd.cmd = ATADETACH; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATADETACH)"); - } - else if (!strcmp(argv[1], "attach") && argc == 3) { - iocmd.cmd = ATAATTACH; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATAATTACH)"); - info_print(fd, iocmd.channel, 0); - } - else if (!strcmp(argv[1], "reinit") && argc == 3) { - iocmd.cmd = ATAREINIT; - if (ioctl(fd, IOCATA, &iocmd) < 0) - warn("ioctl(ATAREINIT)"); - info_print(fd, iocmd.channel, 0); - } - else if (!strcmp(argv[1], "create")) { - int disk, dev, offset; + int maxchannel, channel; - iocmd.cmd = ATARAIDCREATE; + if (ioctl(fd, IOCATAGMAXCHANNEL, &maxchannel) < 0) + err(1, "ioctl(IOCATAGMAXCHANNEL)"); + for (channel = 0; channel < maxchannel; channel++) + info_print(fd, channel, 1); + exit(EX_OK); + } + if (!strcmp(argv[1], "info") && argc == 3) { + int channel; + + if (!(sscanf(argv[2], "ata%d", &channel) == 1)) { + fprintf(stderr, + "atacontrol: Invalid channel %s\n", argv[3]); + exit(EX_USAGE); + } + info_print(fd, channel, 0); + exit(EX_OK); + } + if (!strcmp(argv[1], "detach") && argc == 3) { + int channel; + + if (!(sscanf(argv[2], "ata%d", &channel) == 1)) { + fprintf(stderr, + "atacontrol: Invalid channel %s\n", argv[3]); + exit(EX_USAGE); + } + if (ioctl(fd, IOCATADETACH, &channel) < 0) + err(1, "ioctl(IOCATADETACH)"); + exit(EX_OK); + } + if (!strcmp(argv[1], "attach") && argc == 3) { + int channel; + + if (!(sscanf(argv[2], "ata%d", &channel) == 1)) { + fprintf(stderr, + "atacontrol: Invalid channel %s\n", argv[3]); + exit(EX_USAGE); + } + if (ioctl(fd, IOCATAATTACH, &channel) < 0) + err(1, "ioctl(IOCATAATTACH)"); + info_print(fd, channel, 0); + exit(EX_OK); + } + if (!strcmp(argv[1], "reinit") && argc == 3) { + int channel; + + if (!(sscanf(argv[2], "ata%d", &channel) == 1)) { + fprintf(stderr, + "atacontrol: Invalid channel %s\n", argv[3]); + exit(EX_USAGE); + } + if (ioctl(fd, IOCATAREINIT, &channel) < 0) + warn("ioctl(IOCATAREINIT)"); + info_print(fd, channel, 0); + exit(EX_OK); + } + if (!strcmp(argv[1], "create")) { + int disk, dev, offset; + struct ata_ioc_raid_config config; + + bzero(&config, sizeof(config)); if (argc > 2) { if (!strcasecmp(argv[2], "RAID0") || !strcasecmp(argv[2], "stripe")) - iocmd.u.raid_setup.type = AR_RAID0; + config.type = AR_RAID0; if (!strcasecmp(argv[2], "RAID1") || !strcasecmp(argv[2],"mirror")) - iocmd.u.raid_setup.type = AR_RAID1; + config.type = AR_RAID1; if (!strcasecmp(argv[2], "RAID0+1") || !strcasecmp(argv[2],"RAID10")) - iocmd.u.raid_setup.type = AR_RAID01; + config.type = AR_RAID01; if (!strcasecmp(argv[2], "RAID5")) - iocmd.u.raid_setup.type = AR_RAID5; + config.type = AR_RAID5; if (!strcasecmp(argv[2], "SPAN")) - iocmd.u.raid_setup.type = AR_SPAN; + config.type = AR_SPAN; if (!strcasecmp(argv[2], "JBOD")) - iocmd.u.raid_setup.type = AR_JBOD; + config.type = AR_JBOD; } - if (!iocmd.u.raid_setup.type) { - fprintf(stderr, "atacontrol: Invalid RAID type\n"); - fprintf(stderr, "atacontrol: Valid RAID types : \n"); - fprintf(stderr, " RAID0 | stripe | RAID1 | mirror " - "| RAID0+1 | SPAN | JBOD\n"); + if (!config.type) { + fprintf(stderr, "atacontrol: Invalid RAID type %s\n", + argv[2]); + fprintf(stderr, "atacontrol: Valid RAID types: \n"); + fprintf(stderr, " stripe | mirror | " + "RAID0 | RAID1 | RAID0+1 | RAID5 | " + "SPAN | JBOD\n"); exit(EX_USAGE); } - if (iocmd.u.raid_setup.type == AR_RAID0 || - iocmd.u.raid_setup.type == AR_RAID01 || - iocmd.u.raid_setup.type == AR_RAID5) { + if (config.type == AR_RAID0 || + config.type == AR_RAID01 || + config.type == AR_RAID5) { if (argc < 4 || - !sscanf(argv[3], "%d", - &iocmd.u.raid_setup.interleave) == 1) { - fprintf(stderr, "atacontrol: Invalid interleave\n"); + !sscanf(argv[3], "%d", &config.interleave) == 1) { + fprintf(stderr, + "atacontrol: Invalid interleave %s\n", + argv[3]); exit(EX_USAGE); } offset = 4; @@ -412,82 +449,98 @@ main(int argc, char **argv) offset = 3; for (disk = 0; disk < 16 && (offset + disk) < argc; disk++) { - if (!(sscanf(argv[offset + disk], "%d", &dev) == 1 || - sscanf(argv[offset + disk], "ad%d", &dev) == 1)) { + if (!(sscanf(argv[offset + disk], "ad%d", &dev) == 1)) { fprintf(stderr, - "atacontrol: Invalid device %s\n", + "atacontrol: Invalid disk %s\n", argv[offset + disk]); exit(EX_USAGE); } - iocmd.u.raid_setup.disks[disk] = dev; + config.disks[disk] = dev; } - if(disk < 2) { + if ((config.type == AR_RAID1 || config.type == AR_RAID01) && + disk < 2) { fprintf(stderr, "atacontrol: At least 2 disks must be " - "specified to create RAID\n"); + "specified\n"); exit(EX_USAGE); } - iocmd.u.raid_setup.total_disks = disk; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATARAIDCREATE)"); + config.total_disks = disk; + if (ioctl(fd, IOCATARAIDCREATE, &config) < 0) + err(1, "ioctl(IOCATARAIDCREATE)"); else - printf("ar%d created\n", iocmd.u.raid_setup.unit); + printf("ar%d created\n", config.lun); + exit(EX_OK); } - else if (!strcmp(argv[1], "delete") && argc == 3) { - iocmd.cmd = ATARAIDDELETE; - if (ioctl(fd, IOCATA, &iocmd) < 0) - warn("ioctl(ATARAIDDELETE)"); - } - else if (!strcmp(argv[1], "addspare") && argc == 4) { - int dev; + if (!strcmp(argv[1], "delete") && argc == 3) { + int array; - iocmd.cmd = ATARAIDADDSPARE; - if (!(sscanf(argv[3], "%d", &dev) == 1 || - sscanf(argv[3], "ad%d", &dev) == 1)) { + if (!(sscanf(argv[2], "ar%d", &array) == 1)) { fprintf(stderr, - "atacontrol: Invalid device %s\n", argv[3]); + "atacontrol: Invalid array %s\n", argv[3]); + exit(EX_USAGE); + } + if (ioctl(fd, IOCATARAIDDELETE, &array) < 0) + warn("ioctl(IOCATARAIDDELETE)"); + exit(EX_OK); + } + if (!strcmp(argv[1], "addspare") && argc == 4) { + struct ata_ioc_raid_config config; + + if (!(sscanf(argv[2], "ar%d", &config.lun) == 1)) { + fprintf(stderr, + "atacontrol: Invalid array %s\n", argv[3]); usage(); } - iocmd.u.raid_spare.disk = dev; - if (ioctl(fd, IOCATA, &iocmd) < 0) - warn("ioctl(ATARAIDADDSPARE)"); + if (!(sscanf(argv[3], "ad%d", &config.disks[0]) == 1)) { + fprintf(stderr, + "atacontrol: Invalid disk %s\n", argv[3]); + usage(); + } + if (ioctl(fd, IOCATARAIDADDSPARE, &config) < 0) + warn("ioctl(IOCATARAIDADDSPARE)"); + exit(EX_OK); } - else if (!strcmp(argv[1], "rebuild") && argc == 3) { - iocmd.cmd = ATARAIDREBUILD; - if (ioctl(fd, IOCATA, &iocmd) < 0) - warn("ioctl(ATARAIDREBUILD)"); + if (!strcmp(argv[1], "rebuild") && argc == 3) { + int array; + + if (!(sscanf(argv[2], "ar%d", &array) == 1)) { + fprintf(stderr, + "atacontrol: Invalid array %s\n", argv[3]); + usage(); + } + if (ioctl(fd, IOCATARAIDREBUILD, &array) < 0) + warn("ioctl(IOCATARAIDREBUILD)"); else { char buffer[128]; sprintf(buffer, "/usr/bin/nice -n 20 /bin/dd " "if=/dev/ar%d of=/dev/null bs=1m &", - iocmd.channel); + array); if (system(buffer)) warn("background dd"); } + exit(EX_OK); } - else if (!strcmp(argv[1], "status") && argc == 3) { + if (!strcmp(argv[1], "status") && argc == 3) { + struct ata_ioc_raid_config config; int i; - iocmd.cmd = ATARAIDSTATUS; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATARAIDSTATUS)"); - printf("ar%d: ATA ", iocmd.channel); - switch (iocmd.u.raid_status.type) { + if (ioctl(fd, IOCATARAIDSTATUS, &config) < 0) + err(1, "ioctl(IOCATARAIDSTATUS)"); + + printf("ar%d: ATA ", config.lun); + switch (config.type) { case AR_RAID0: - printf("RAID0 stripesize=%d", - iocmd.u.raid_status.interleave); + printf("RAID0 stripesize=%d", config.interleave); break; case AR_RAID1: printf("RAID1"); break; case AR_RAID01: - printf("RAID0+1 stripesize=%d", - iocmd.u.raid_status.interleave); + printf("RAID0+1 stripesize=%d", config.interleave); break; case AR_RAID5: - printf("RAID5 stripesize=%d", - iocmd.u.raid_status.interleave); + printf("RAID5 stripesize=%d", config.interleave); break; case AR_JBOD: printf("JBOD"); @@ -496,14 +549,14 @@ main(int argc, char **argv) break; } printf(" subdisks: "); - for (i = 0; i < iocmd.u.raid_status.total_disks; i++) { - if (iocmd.u.raid_status.disks[i] >= 0) - printf("ad%d ", iocmd.u.raid_status.disks[i]); + for (i = 0; i < config.total_disks; i++) { + if (config.disks[i] >= 0) + printf("ad%d ", config.disks[i]); else printf("DOWN "); } printf("status: "); - switch (iocmd.u.raid_status.status) { + switch (config.status) { case AR_READY: printf("READY\n"); break; @@ -512,32 +565,13 @@ main(int argc, char **argv) break; case AR_READY | AR_DEGRADED | AR_REBUILDING: printf("REBUILDING %d%% completed\n", - iocmd.u.raid_status.progress); + config.progress); break; default: printf("BROKEN\n"); } + exit(EX_OK); } - else if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 5)) { - if (argc == 5) { - iocmd.cmd = ATASMODE; - iocmd.device = -1; - iocmd.u.mode.mode[0] = str2mode(argv[3]); - iocmd.u.mode.mode[1] = str2mode(argv[4]); - if (ioctl(fd, IOCATA, &iocmd) < 0) - warn("ioctl(ATASMODE)"); - } - if (argc == 3 || argc == 5) { - iocmd.cmd = ATAGMODE; - iocmd.device = -1; - if (ioctl(fd, IOCATA, &iocmd) < 0) - err(1, "ioctl(ATAGMODE)"); - printf("Master = %s \nSlave = %s\n", - mode2str(iocmd.u.mode.mode[0]), - mode2str(iocmd.u.mode.mode[1])); - } - } - else - usage(); + usage(); exit(EX_OK); } diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 57534a66a64a..6b70448bf827 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #endif #include -#include #include /* device structure */ @@ -75,7 +74,7 @@ static void bpack(int8_t *, int8_t *, int); /* global vars */ MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); -int (*ata_ioctl_func)(struct ata_cmd *iocmd) = NULL; +int (*ata_raid_ioctl_func)(u_long cmd, caddr_t data) = NULL; devclass_t ata_devclass; uma_zone_t ata_request_zone; uma_zone_t ata_composite_zone; @@ -338,209 +337,167 @@ ata_interrupt(void *data) * device related interfaces */ static int -ata_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, +ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int32_t flag, struct thread *td) { - struct ata_cmd *iocmd = (struct ata_cmd *)addr; - device_t *children, device = NULL; - struct ata_request *request; - caddr_t buf; - int nchildren, i; - int error = ENOTTY; + device_t device, *children; + struct ata_ioc_devices *devices = (struct ata_ioc_devices *)data; + int *value = (int *)data; + int i, nchildren, error = ENOTTY; - if (cmd != IOCATA) - return ENOTSUP; - if (iocmd->cmd == ATAGMAXCHANNEL) { - iocmd->u.maxchan = devclass_get_maxunit(ata_devclass); - return 0; - } - if (iocmd->channel < 0 || - iocmd->channel >= devclass_get_maxunit(ata_devclass)) { - return ENXIO; - } - if (!(device = devclass_get_device(ata_devclass, iocmd->channel))) - return ENXIO; - - switch (iocmd->cmd) { - case ATAGPARM: - if (!device_get_children(device, &children, &nchildren)) { - struct ata_channel *ch; - - if (!(ch = device_get_softc(device))) - return ENXIO; - iocmd->u.param.type[0] = - ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER); - iocmd->u.param.type[1] = - ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE); - for (i = 0; i < nchildren; i++) { - if (children[i] && device_is_attached(children[i])) { - struct ata_device *atadev = device_get_softc(children[i]); - - if (atadev->unit == ATA_MASTER) { - strcpy(iocmd->u.param.name[0], - device_get_nameunit(children[i])); - bcopy(&atadev->param, &iocmd->u.param.params[0], - sizeof(struct ata_params)); - } - if (atadev->unit == ATA_SLAVE) { - strcpy(iocmd->u.param.name[1], - device_get_nameunit(children[i])); - bcopy(&atadev->param, &iocmd->u.param.params[1], - sizeof(struct ata_params)); - } - } - } - free(children, M_TEMP); - error = 0; - } - else - error = ENXIO; + switch (cmd) { + case IOCATAGMAXCHANNEL: + *value = devclass_get_maxunit(ata_devclass); + error = 0; break; - case ATAGMODE: - if (!device_get_children(device, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) { - if (children[i] && device_is_attached(children[i])) { - struct ata_device *atadev = device_get_softc(children[i]); - - atadev = device_get_softc(children[i]); - if (atadev->unit == ATA_MASTER) - iocmd->u.mode.mode[0] = atadev->mode; - if (atadev->unit == ATA_SLAVE) - iocmd->u.mode.mode[1] = atadev->mode; - } - free(children, M_TEMP); - } - error = 0; - } - else - error = ENXIO; - break; - - case ATASMODE: - if (!device_get_children(device, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) { - if (children[i] && device_is_attached(children[i])) { - struct ata_device *atadev = device_get_softc(children[i]); - - if (atadev->unit == ATA_MASTER) { - atadev->mode = iocmd->u.mode.mode[0]; - ATA_SETMODE(device, children[i]); - iocmd->u.mode.mode[0] = atadev->mode; - } - if (atadev->unit == ATA_SLAVE) { - atadev->mode = iocmd->u.mode.mode[1]; - ATA_SETMODE(device, children[i]); - iocmd->u.mode.mode[1] = atadev->mode; - } - } - } - free(children, M_TEMP); - error = 0; - } - else - error = ENXIO; - break; - - case ATAREQUEST: - if (!device_get_children(device, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) { - if (children[i] && device_is_attached(children[i])) { - struct ata_device *atadev = device_get_softc(children[i]); - - if (ATA_DEV(atadev->unit) == iocmd->device) { - if (!(buf = malloc(iocmd->u.request.count, - M_ATA, M_NOWAIT))) { - error = ENOMEM; - break; - } - if (!(request = ata_alloc_request())) { - error = ENOMEM; - free(buf, M_ATA); - break; - } - if (iocmd->u.request.flags & ATA_CMD_WRITE) { - error = copyin(iocmd->u.request.data, buf, - iocmd->u.request.count); - if (error) { - free(buf, M_ATA); - ata_free_request(request); - break; - } - } - request->dev = atadev->dev; - if (iocmd->u.request.flags & ATA_CMD_ATAPI) { - request->flags = ATA_R_ATAPI; - bcopy(iocmd->u.request.u.atapi.ccb, - request->u.atapi.ccb, 16); - } - else { - request->u.ata.command = - iocmd->u.request.u.ata.command; - request->u.ata.feature = - iocmd->u.request.u.ata.feature; - request->u.ata.lba = iocmd->u.request.u.ata.lba; - request->u.ata.count = iocmd->u.request.u.ata.count; - } - request->timeout = iocmd->u.request.timeout; - request->data = buf; - request->bytecount = iocmd->u.request.count; - request->transfersize = request->bytecount; - if (iocmd->u.request.flags & ATA_CMD_CONTROL) - request->flags |= ATA_R_CONTROL; - if (iocmd->u.request.flags & ATA_CMD_READ) - request->flags |= ATA_R_READ; - if (iocmd->u.request.flags & ATA_CMD_WRITE) - request->flags |= ATA_R_WRITE; - ata_queue_request(request); - if (!(request->flags & ATA_R_ATAPI)) { - iocmd->u.request.u.ata.command = - request->u.ata.command; - iocmd->u.request.u.ata.feature = - request->u.ata.feature; - iocmd->u.request.u.ata.lba = request->u.ata.lba; - iocmd->u.request.u.ata.count = request->u.ata.count; - } - iocmd->u.request.error = request->result; - if (iocmd->u.request.flags & ATA_CMD_READ) - error = copyout(buf, iocmd->u.request.data, - iocmd->u.request.count); - else - error = 0; - free(buf, M_ATA); - ata_free_request(request); - break; - } - } - } - free(children, M_TEMP); - } - else - error = ENXIO; - break; - - case ATAREINIT: + case IOCATAREINIT: + if (*value > devclass_get_maxunit(ata_devclass) || + !(device = devclass_get_device(ata_devclass, *value))) + return ENXIO; error = ata_reinit(device); ata_start(device); break; - case ATAATTACH: + case IOCATAATTACH: + if (*value > devclass_get_maxunit(ata_devclass) || + !(device = devclass_get_device(ata_devclass, *value))) + return ENXIO; /* XXX SOS should enable channel HW on controller */ error = ata_attach(device); break; - case ATADETACH: + case IOCATADETACH: + if (*value > devclass_get_maxunit(ata_devclass) || + !(device = devclass_get_device(ata_devclass, *value))) + return ENXIO; error = ata_detach(device); /* XXX SOS should disable channel HW on controller */ break; + case IOCATADEVICES: + if (devices->channel > devclass_get_maxunit(ata_devclass) || + !(device = devclass_get_device(ata_devclass, devices->channel))) + return ENXIO; + bzero(devices->name[0], 32); + bzero(&devices->params[0], sizeof(struct ata_params)); + bzero(devices->name[1], 32); + bzero(&devices->params[1], sizeof(struct ata_params)); + if (!device_get_children(device, &children, &nchildren)) { + for (i = 0; i < nchildren; i++) { + if (children[i] && device_is_attached(children[i])) { + struct ata_device *atadev = device_get_softc(children[i]); + + if (atadev->unit == ATA_MASTER) { + strncpy(devices->name[0], + device_get_nameunit(children[i]), 32); + bcopy(&atadev->param, &devices->params[0], + sizeof(struct ata_params)); + } + if (atadev->unit == ATA_SLAVE) { + strncpy(devices->name[1], + device_get_nameunit(children[i]), 32); + bcopy(&atadev->param, &devices->params[1], + sizeof(struct ata_params)); + } + } + } + free(children, M_TEMP); + error = 0; + } + else + error = ENODEV; + break; + default: - if (ata_ioctl_func) - error = ata_ioctl_func(iocmd); + if (ata_raid_ioctl_func) + error = ata_raid_ioctl_func(cmd, data); } return error; } +int +ata_device_ioctl(device_t dev, u_long cmd, caddr_t data) +{ + struct ata_device *atadev = device_get_softc(dev); + struct ata_ioc_request *ioc_request = (struct ata_ioc_request *)data; + struct ata_params *params = (struct ata_params *)data; + int *mode = (int *)data; + struct ata_request *request; + caddr_t buf; + int error; + + switch (cmd) { + case IOCATAREQUEST: + if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) { + return ENOMEM; + } + if (!(request = ata_alloc_request())) { + free(buf, M_ATA); + return ENOMEM; + } + if (ioc_request->flags & ATA_CMD_WRITE) { + error = copyin(ioc_request->data, buf, ioc_request->count); + if (error) { + free(buf, M_ATA); + ata_free_request(request); + return error; + } + } + request->dev = dev; + if (ioc_request->flags & ATA_CMD_ATAPI) { + request->flags = ATA_R_ATAPI; + bcopy(ioc_request->u.atapi.ccb, request->u.atapi.ccb, 16); + } + else { + request->u.ata.command = ioc_request->u.ata.command; + request->u.ata.feature = ioc_request->u.ata.feature; + request->u.ata.lba = ioc_request->u.ata.lba; + request->u.ata.count = ioc_request->u.ata.count; + } + request->timeout = ioc_request->timeout; + request->data = buf; + request->bytecount = ioc_request->count; + request->transfersize = request->bytecount; + if (ioc_request->flags & ATA_CMD_CONTROL) + request->flags |= ATA_R_CONTROL; + if (ioc_request->flags & ATA_CMD_READ) + request->flags |= ATA_R_READ; + if (ioc_request->flags & ATA_CMD_WRITE) + request->flags |= ATA_R_WRITE; + ata_queue_request(request); + if (!(request->flags & ATA_R_ATAPI)) { + ioc_request->u.ata.command = request->u.ata.command; + ioc_request->u.ata.feature = request->u.ata.feature; + ioc_request->u.ata.lba = request->u.ata.lba; + ioc_request->u.ata.count = request->u.ata.count; + } + ioc_request->error = request->result; + if (ioc_request->flags & ATA_CMD_READ) + error = copyout(buf, ioc_request->data, ioc_request->count); + else + error = 0; + free(buf, M_ATA); + ata_free_request(request); + return error; + + case IOCATAGPARM: + bcopy(&atadev->param, params, sizeof(struct ata_params)); + return 0; + + case IOCATASMODE: + atadev->mode = *mode; + ATA_SETMODE(device_get_parent(dev), dev); + return 0; + + case IOCATAGMODE: + *mode = atadev->mode; + return 0; + default: + return ENOTTY; + } +} + static void ata_boot_attach(void) { @@ -572,12 +529,7 @@ ata_add_child(device_t parent, struct ata_device *atadev, int unit) device_t child; if ((child = device_add_child(parent, NULL, unit))) { - char buffer[64]; - device_set_softc(child, atadev); - sprintf(buffer, "%.40s/%.8s", - atadev->param.model, atadev->param.revision); - device_set_desc_copy(child, buffer); device_quiet(child); atadev->dev = child; atadev->max_iosize = DEV_BSIZE; @@ -623,6 +575,7 @@ ata_getparam(device_t parent, struct ata_device *atadev) if (!error && (isprint(atadev->param.model[0]) || isprint(atadev->param.model[1]))) { struct ata_params *atacap = &atadev->param; + char buffer[64]; #if BYTE_ORDER == BIG_ENDIAN int16_t *ptr; @@ -645,6 +598,8 @@ ata_getparam(device_t parent, struct ata_device *atadev) bpack(atacap->revision, atacap->revision, sizeof(atacap->revision)); btrim(atacap->serial, sizeof(atacap->serial)); bpack(atacap->serial, atacap->serial, sizeof(atacap->serial)); + sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision); + device_set_desc_copy(atadev->dev, buffer); if (bootverbose) printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n", ch->unit, atadev->unit == ATA_MASTER ? "master":"slave", @@ -754,26 +709,26 @@ ata_modify_if_48bit(struct ata_request *request) request->u.ata.count > 256) && atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { - /* translate command into 48bit version */ - switch (command) { - case ATA_READ: - command = ATA_READ48; break; - case ATA_READ_MUL: - command = ATA_READ_MUL48; break; - case ATA_READ_DMA: - command = ATA_READ_DMA48; break; - case ATA_READ_DMA_QUEUED: - command = ATA_READ_DMA_QUEUED48; break; - case ATA_WRITE: - command = ATA_WRITE48; break; - case ATA_WRITE_MUL: - command = ATA_WRITE_MUL48; break; - case ATA_WRITE_DMA: - command = ATA_WRITE_DMA48; break; - case ATA_WRITE_DMA_QUEUED: - command = ATA_WRITE_DMA_QUEUED48; break; - case ATA_FLUSHCACHE: - command = ATA_FLUSHCACHE48; break; + /* translate command into 48bit version */ + switch (command) { + case ATA_READ: + command = ATA_READ48; break; + case ATA_READ_MUL: + command = ATA_READ_MUL48; break; + case ATA_READ_DMA: + command = ATA_READ_DMA48; break; + case ATA_READ_DMA_QUEUED: + command = ATA_READ_DMA_QUEUED48; break; + case ATA_WRITE: + command = ATA_WRITE48; break; + case ATA_WRITE_MUL: + command = ATA_WRITE_MUL48; break; + case ATA_WRITE_DMA: + command = ATA_WRITE_DMA48; break; + case ATA_WRITE_DMA_QUEUED: + command = ATA_WRITE_DMA_QUEUED48; break; + case ATA_FLUSHCACHE: + command = ATA_FLUSHCACHE48; break; default: return command; } diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 47b9604512e4..396a0fdee883 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -163,87 +163,87 @@ #define ATA_SC_IPM_DIS_PARTIAL 0x00000100 #define ATA_SC_IPM_DIS_SLUMBER 0x00000200 -#define ATA_SACTIVE 16 +#define ATA_SACTIVE 16 /* SATA AHCI v1.0 register defines */ -#define ATA_AHCI_CAP 0x00 -#define ATA_AHCI_NPMASK 0x1f +#define ATA_AHCI_CAP 0x00 +#define ATA_AHCI_NPMASK 0x1f -#define ATA_AHCI_GHC 0x04 -#define ATA_AHCI_GHC_AE 0x80000000 -#define ATA_AHCI_GHC_IE 0x00000002 -#define ATA_AHCI_GHC_HR 0x80000001 +#define ATA_AHCI_GHC 0x04 +#define ATA_AHCI_GHC_AE 0x80000000 +#define ATA_AHCI_GHC_IE 0x00000002 +#define ATA_AHCI_GHC_HR 0x80000001 -#define ATA_AHCI_IS 0x08 -#define ATA_AHCI_PI 0x0c -#define ATA_AHCI_VS 0x10 +#define ATA_AHCI_IS 0x08 +#define ATA_AHCI_PI 0x0c +#define ATA_AHCI_VS 0x10 -#define ATA_AHCI_OFFSET 0x80 +#define ATA_AHCI_OFFSET 0x80 -#define ATA_AHCI_P_CLB 0x100 -#define ATA_AHCI_P_CLBU 0x104 -#define ATA_AHCI_P_FB 0x108 -#define ATA_AHCI_P_FBU 0x10c -#define ATA_AHCI_P_IS 0x110 -#define ATA_AHCI_P_IE 0x114 -#define ATA_AHCI_P_IX_DHR 0x00000001 -#define ATA_AHCI_P_IX_PS 0x00000002 -#define ATA_AHCI_P_IX_DS 0x00000004 -#define ATA_AHCI_P_IX_SDB 0x00000008 -#define ATA_AHCI_P_IX_UF 0x00000010 -#define ATA_AHCI_P_IX_DP 0x00000020 -#define ATA_AHCI_P_IX_PC 0x00000040 -#define ATA_AHCI_P_IX_DI 0x00000080 +#define ATA_AHCI_P_CLB 0x100 +#define ATA_AHCI_P_CLBU 0x104 +#define ATA_AHCI_P_FB 0x108 +#define ATA_AHCI_P_FBU 0x10c +#define ATA_AHCI_P_IS 0x110 +#define ATA_AHCI_P_IE 0x114 +#define ATA_AHCI_P_IX_DHR 0x00000001 +#define ATA_AHCI_P_IX_PS 0x00000002 +#define ATA_AHCI_P_IX_DS 0x00000004 +#define ATA_AHCI_P_IX_SDB 0x00000008 +#define ATA_AHCI_P_IX_UF 0x00000010 +#define ATA_AHCI_P_IX_DP 0x00000020 +#define ATA_AHCI_P_IX_PC 0x00000040 +#define ATA_AHCI_P_IX_DI 0x00000080 -#define ATA_AHCI_P_IX_PRC 0x00400000 -#define ATA_AHCI_P_IX_IPM 0x00800000 -#define ATA_AHCI_P_IX_OF 0x01000000 -#define ATA_AHCI_P_IX_INF 0x04000000 -#define ATA_AHCI_P_IX_IF 0x08000000 -#define ATA_AHCI_P_IX_HBD 0x10000000 -#define ATA_AHCI_P_IX_HBF 0x20000000 -#define ATA_AHCI_P_IX_TFE 0x40000000 -#define ATA_AHCI_P_IX_CPD 0x80000000 +#define ATA_AHCI_P_IX_PRC 0x00400000 +#define ATA_AHCI_P_IX_IPM 0x00800000 +#define ATA_AHCI_P_IX_OF 0x01000000 +#define ATA_AHCI_P_IX_INF 0x04000000 +#define ATA_AHCI_P_IX_IF 0x08000000 +#define ATA_AHCI_P_IX_HBD 0x10000000 +#define ATA_AHCI_P_IX_HBF 0x20000000 +#define ATA_AHCI_P_IX_TFE 0x40000000 +#define ATA_AHCI_P_IX_CPD 0x80000000 -#define ATA_AHCI_P_CMD 0x118 -#define ATA_AHCI_P_CMD_ST 0x00000001 -#define ATA_AHCI_P_CMD_SUD 0x00000002 -#define ATA_AHCI_P_CMD_POD 0x00000004 -#define ATA_AHCI_P_CMD_CLO 0x00000008 -#define ATA_AHCI_P_CMD_FRE 0x00000010 -#define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00 -#define ATA_AHCI_P_CMD_ISS 0x00002000 -#define ATA_AHCI_P_CMD_FR 0x00004000 -#define ATA_AHCI_P_CMD_CR 0x00008000 -#define ATA_AHCI_P_CMD_CPS 0x00010000 -#define ATA_AHCI_P_CMD_PMA 0x00020000 -#define ATA_AHCI_P_CMD_HPCP 0x00040000 -#define ATA_AHCI_P_CMD_ISP 0x00080000 -#define ATA_AHCI_P_CMD_CPD 0x00100000 -#define ATA_AHCI_P_CMD_ATAPI 0x01000000 -#define ATA_AHCI_P_CMD_DLAE 0x02000000 -#define ATA_AHCI_P_CMD_ALPE 0x04000000 -#define ATA_AHCI_P_CMD_ASP 0x08000000 -#define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000 -#define ATA_AHCI_P_CMD_NOOP 0x00000000 -#define ATA_AHCI_P_CMD_ACTIVE 0x10000000 -#define ATA_AHCI_P_CMD_PARTIAL 0x20000000 -#define ATA_AHCI_P_CMD_SLUMPER 0x60000000 +#define ATA_AHCI_P_CMD 0x118 +#define ATA_AHCI_P_CMD_ST 0x00000001 +#define ATA_AHCI_P_CMD_SUD 0x00000002 +#define ATA_AHCI_P_CMD_POD 0x00000004 +#define ATA_AHCI_P_CMD_CLO 0x00000008 +#define ATA_AHCI_P_CMD_FRE 0x00000010 +#define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00 +#define ATA_AHCI_P_CMD_ISS 0x00002000 +#define ATA_AHCI_P_CMD_FR 0x00004000 +#define ATA_AHCI_P_CMD_CR 0x00008000 +#define ATA_AHCI_P_CMD_CPS 0x00010000 +#define ATA_AHCI_P_CMD_PMA 0x00020000 +#define ATA_AHCI_P_CMD_HPCP 0x00040000 +#define ATA_AHCI_P_CMD_ISP 0x00080000 +#define ATA_AHCI_P_CMD_CPD 0x00100000 +#define ATA_AHCI_P_CMD_ATAPI 0x01000000 +#define ATA_AHCI_P_CMD_DLAE 0x02000000 +#define ATA_AHCI_P_CMD_ALPE 0x04000000 +#define ATA_AHCI_P_CMD_ASP 0x08000000 +#define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000 +#define ATA_AHCI_P_CMD_NOOP 0x00000000 +#define ATA_AHCI_P_CMD_ACTIVE 0x10000000 +#define ATA_AHCI_P_CMD_PARTIAL 0x20000000 +#define ATA_AHCI_P_CMD_SLUMPER 0x60000000 -#define ATA_AHCI_P_TFD 0x120 -#define ATA_AHCI_P_SIG 0x124 -#define ATA_AHCI_P_SSTS 0x128 -#define ATA_AHCI_P_SCTL 0x12c -#define ATA_AHCI_P_SERR 0x130 -#define ATA_AHCI_P_SACT 0x134 -#define ATA_AHCI_P_CI 0x138 +#define ATA_AHCI_P_TFD 0x120 +#define ATA_AHCI_P_SIG 0x124 +#define ATA_AHCI_P_SSTS 0x128 +#define ATA_AHCI_P_SCTL 0x12c +#define ATA_AHCI_P_SERR 0x130 +#define ATA_AHCI_P_SACT 0x134 +#define ATA_AHCI_P_CI 0x138 -#define ATA_AHCI_CL_SIZE 32 -#define ATA_AHCI_CL_OFFSET 0 -#define ATA_AHCI_FB_OFFSET 1024 -#define ATA_AHCI_CT_OFFSET 1024+256 -#define ATA_AHCI_CT_SG_OFFSET 128 -#define ATA_AHCI_CT_SIZE 256 +#define ATA_AHCI_CL_SIZE 32 +#define ATA_AHCI_CL_OFFSET 0 +#define ATA_AHCI_FB_OFFSET 1024 +#define ATA_AHCI_CT_OFFSET 1024+256 +#define ATA_AHCI_CT_SG_OFFSET 128 +#define ATA_AHCI_CT_SIZE 256 /* DMA register defines */ #define ATA_DMA_ENTRIES 256 @@ -521,7 +521,7 @@ struct ata_channel { #define ATA_LED_MASK 0x03 /* externs */ -extern int (*ata_ioctl_func)(struct ata_cmd *iocmd); +extern int (*ata_raid_ioctl_func)(u_long cmd, caddr_t data); extern devclass_t ata_devclass; extern int ata_wc; @@ -533,6 +533,7 @@ int ata_detach(device_t dev); int ata_reinit(device_t dev); int ata_suspend(device_t dev); int ata_resume(device_t dev); +int ata_device_ioctl(device_t dev, u_long cmd, caddr_t data); int ata_identify(device_t dev); void ata_default_registers(device_t dev); u_int8_t ata_modify_if_48bit(struct ata_request *request); diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index 03162fee34f3..1c0541c5bef1 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -250,15 +250,15 @@ ata_sata_connect(struct ata_channel *ch) if (bootverbose) device_printf(ch->dev, "SATA connect ready time=%dms\n", timeout * 10); if (timeout < 1000) { - if ((ATA_IDX_INB(ch, ATA_CYL_LSB) == ATAPI_MAGIC_LSB) && + if ((ATA_IDX_INB(ch, ATA_CYL_LSB) == ATAPI_MAGIC_LSB) && (ATA_IDX_INB(ch, ATA_CYL_MSB) == ATAPI_MAGIC_MSB)) ch->devices = ATA_ATAPI_MASTER; - else + else ch->devices = ATA_ATA_MASTER; } if (bootverbose) - device_printf(ch->dev, "sata_connect devices=0x%b\n", - ch->devices, "\20\3ATAPI_MASTER\1ATA_MASTER"); + device_printf(ch->dev, "sata_connect devices=0x%b\n", + ch->devices, "\20\3ATAPI_MASTER\1ATA_MASTER"); return 1; } @@ -325,25 +325,25 @@ ata_sata_phy_event(void *context, int dummy) * AHCI v1.0 compliant SATA chipset support functions */ struct ata_ahci_dma_prd { - u_int64_t dba; - u_int32_t reserved; - u_int32_t dbc; /* 0 based */ -#define ATA_AHCI_PRD_MASK 0x003fffff /* max 4MB */ -#define ATA_AHCI_PRD_IPC (1<<31) + u_int64_t dba; + u_int32_t reserved; + u_int32_t dbc; /* 0 based */ +#define ATA_AHCI_PRD_MASK 0x003fffff /* max 4MB */ +#define ATA_AHCI_PRD_IPC (1<<31) } __packed; struct ata_ahci_cmd_tab { - u_int8_t cfis[64]; - u_int8_t acmd[32]; - u_int8_t reserved[32]; - struct ata_ahci_dma_prd prd_tab[16]; + u_int8_t cfis[64]; + u_int8_t acmd[32]; + u_int8_t reserved[32]; + struct ata_ahci_dma_prd prd_tab[16]; } __packed; struct ata_ahci_cmd_list { - u_int16_t cmd_flags; - u_int16_t prd_length; /* PRD entries */ - u_int32_t bytecount; - u_int64_t cmd_table_phys; /* 128byte aligned */ + u_int16_t cmd_flags; + u_int16_t prd_length; /* PRD entries */ + u_int32_t bytecount; + u_int64_t cmd_table_phys; /* 128byte aligned */ } __packed; @@ -376,7 +376,7 @@ ata_ahci_allocate(device_t dev) ch->hw.begin_transaction = ata_ahci_begin_transaction; ch->hw.end_transaction = ata_ahci_end_transaction; - ch->hw.command = NULL; /* not used here */ + ch->hw.command = NULL; /* not used here */ /* setup the work areas */ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, @@ -409,8 +409,8 @@ ata_ahci_setup_fis(u_int8_t *fis, struct ata_request *request) int idx = 0; /* XXX SOS add ATAPI commands support later */ - fis[idx++] = 0x27; /* host to device */ - fis[idx++] = 0x80; /* command FIS (note PM goes here) */ + fis[idx++] = 0x27; /* host to device */ + fis[idx++] = 0x80; /* command FIS (note PM goes here) */ fis[idx++] = ata_modify_if_48bit(request); fis[idx++] = request->u.ata.feature; @@ -460,13 +460,13 @@ ata_ahci_begin_transaction(struct ata_request *request) /* if request moves data setup and load SG list */ if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { - if (ch->dma->load(ch->dev, request->data, request->bytecount, - request->flags & ATA_R_READ, + if (ch->dma->load(ch->dev, request->data, request->bytecount, + request->flags & ATA_R_READ, ctp->prd_tab, &entries)) { device_printf(request->dev, "setting up DMA failed\n"); request->result = EIO; return ATA_OP_FINISHED; - } + } } /* setup the command list entry */ @@ -475,11 +475,11 @@ ata_ahci_begin_transaction(struct ata_request *request) clp->prd_length = entries; clp->cmd_flags = (request->flags & ATA_R_WRITE ? (1<<6) : 0) | - (request->flags & ATA_R_ATAPI ? (1<<5) : 0) | - (fis_size / sizeof(u_int32_t)); + (request->flags & ATA_R_ATAPI ? (1<<5) : 0) | + (fis_size / sizeof(u_int32_t)); clp->bytecount = 0; clp->cmd_table_phys = htole64(ch->dma->work_bus + ATA_AHCI_CT_OFFSET + - (ATA_AHCI_CT_SIZE * tag)); + (ATA_AHCI_CT_SIZE * tag)); /* clear eventual ACTIVE bit */ ATA_IDX_OUTL(ch, ATA_SACTIVE, ATA_IDX_INL(ch, ATA_SACTIVE) & (1 << tag)); @@ -516,7 +516,7 @@ ata_ahci_end_transaction(struct ata_request *request) /* record how much data we actually moved */ clp = (struct ata_ahci_cmd_list *) - (ch->dma->work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE * tag)); + (ch->dma->work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE * tag)); request->donecount = clp->bytecount; /* release SG list etc */ @@ -542,11 +542,11 @@ ata_ahci_intr(void *data) struct ata_connect_task *tp; int offset = (ch->unit << 7); - error = ATA_INL(ctlr->r_res2, ATA_AHCI_P_SERR + offset); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_SERR + offset, error); - status = ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IS + offset, status); - issued = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CI + offset); + error = ATA_INL(ctlr->r_res2, ATA_AHCI_P_SERR + offset); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_SERR + offset, error); + status = ATA_INL(ctlr->r_res2, ATA_AHCI_P_IS + offset); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IS + offset, status); + issued = ATA_INL(ctlr->r_res2, ATA_AHCI_P_CI + offset); /* do we have cold connect surprise */ if (status & ATA_AHCI_P_IX_CPD) { @@ -554,24 +554,24 @@ ata_ahci_intr(void *data) status, error, issued); } - /* check for and handle connect events */ - if ((status & ATA_AHCI_P_IX_PC) && + /* check for and handle connect events */ + if ((status & ATA_AHCI_P_IX_PC) && (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), - M_ATA, M_NOWAIT | M_ZERO))) { + malloc(sizeof(struct ata_connect_task), + M_ATA, M_NOWAIT | M_ZERO))) { device_printf(ch->dev, "CONNECT requested\n"); tp->action = ATA_C_ATTACH; tp->dev = ch->dev; TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); taskqueue_enqueue(taskqueue_thread, &tp->task); - } + } - /* check for and handle disconnect events */ - if (((status & (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC)) == + /* check for and handle disconnect events */ + if (((status & (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC)) == ATA_AHCI_P_IX_PRC) && (tp = (struct ata_connect_task *) - malloc(sizeof(struct ata_connect_task), + malloc(sizeof(struct ata_connect_task), M_ATA, M_NOWAIT | M_ZERO))) { device_printf(ch->dev, "DISCONNECT requested\n"); @@ -579,11 +579,11 @@ ata_ahci_intr(void *data) tp->dev = ch->dev; TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); taskqueue_enqueue(taskqueue_thread, &tp->task); - } + } - /* any drive action to take care of ? */ - if (!(issued & (1<interrupt[unit].function(ch); + /* any drive action to take care of ? */ + if (!(issued & (1<interrupt[unit].function(ch); } } } @@ -604,7 +604,7 @@ ata_ahci_reset(device_t dev) cmd & ~(ATA_AHCI_P_CMD_CR | ATA_AHCI_P_CMD_FR | ATA_AHCI_P_CMD_FRE | ATA_AHCI_P_CMD_ST)); - DELAY(500000); /* XXX SOS this is not entirely wrong */ + DELAY(500000); /* XXX SOS this is not entirely wrong */ /* spin up device */ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, ATA_AHCI_P_CMD_SUD); @@ -1426,10 +1426,10 @@ ata_intel_chipinit(device_t dev) &ctlr->r_rid2, RF_ACTIVE))) { if (bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle) || bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, - ata_ahci_intr, ctlr, &ctlr->handle)) { - device_printf(dev, "unable to setup interrupt\n"); - return ENXIO; - } + ata_ahci_intr, ctlr, &ctlr->handle)) { + device_printf(dev, "unable to setup interrupt\n"); + return ENXIO; + } /* force all ports active "the legacy way" */ pci_write_config(dev, 0x92, pci_read_config(dev, 0x92, 2) | 0x0f,2); diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index 64ba57904462..64a41726aeba 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -61,6 +61,7 @@ static void ad_done(struct ata_request *); static void ad_describe(device_t dev); static int ad_version(u_int16_t); static disk_strategy_t ad_strategy; +static disk_ioctl_t ad_ioctl; static dumper_t ad_dump; /* local vars */ @@ -137,6 +138,7 @@ ad_attach(device_t dev) /* create the disk device */ adp->disk = disk_alloc(); adp->disk->d_strategy = ad_strategy; + adp->disk->d_ioctl = ad_ioctl; adp->disk->d_dump = ad_dump; adp->disk->d_name = "ad"; adp->disk->d_drv1 = dev; @@ -282,6 +284,12 @@ ad_done(struct ata_request *request) ata_free_request(request); } +static int +ad_ioctl(struct disk *disk, u_long cmd, void *data, int flag, struct thread *td) +{ + return ata_device_ioctl(disk->d_drv1, cmd, data); +} + static int ad_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 0f74bc3b6fcb..2a40e003af1a 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -667,9 +666,9 @@ ata_generic_command(struct ata_request *request) ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); if (request->flags & ATA_R_ATAPI) { - int timeout = 5000; + int timeout = 5000; - /* issue packet command to controller */ + /* issue packet command to controller */ if (request->flags & ATA_R_DMA) { ATA_IDX_OUTB(ch, ATA_FEATURE, ATA_F_DMA); ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0); @@ -683,32 +682,32 @@ ata_generic_command(struct ata_request *request) ATA_IDX_OUTB(ch, ATA_COMMAND, ATA_PACKET_CMD); /* command interrupt device ? just return and wait for interrupt */ - if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) + if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) return 0; /* wait for ready to write ATAPI command block */ - while (timeout--) { - int reason = ATA_IDX_INB(ch, ATA_IREASON); - int status = ATA_IDX_INB(ch, ATA_STATUS); + while (timeout--) { + int reason = ATA_IDX_INB(ch, ATA_IREASON); + int status = ATA_IDX_INB(ch, ATA_STATUS); - if (((reason & (ATA_I_CMD | ATA_I_IN)) | - (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) - break; - DELAY(20); - } - if (timeout <= 0) { - device_printf(request->dev,"timeout waiting for ATAPI ready\n"); - request->result = EIO; - return -1; - } + if (((reason & (ATA_I_CMD | ATA_I_IN)) | + (status & (ATA_S_DRQ | ATA_S_BUSY))) == ATAPI_P_CMDOUT) + break; + DELAY(20); + } + if (timeout <= 0) { + device_printf(request->dev,"timeout waiting for ATAPI ready\n"); + request->result = EIO; + return -1; + } - /* this seems to be needed for some (slow) devices */ - DELAY(10); - - /* output command block */ - ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, - (atadev->param.config & ATA_PROTO_MASK) == - ATA_PROTO_ATAPI_12 ? 6 : 8); + /* this seems to be needed for some (slow) devices */ + DELAY(10); + + /* output command block */ + ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (int16_t *)request->u.atapi.ccb, + (atadev->param.config & ATA_PROTO_MASK) == + ATA_PROTO_ATAPI_12 ? 6 : 8); } else { u_int8_t command = ata_modify_if_48bit(request); @@ -726,42 +725,42 @@ ata_generic_command(struct ata_request *request) ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); } - else { + else { command = request->u.ata.command; ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; + int heads, sectors; - if (atadev->param.atavalid & ATA_FLAG_54_58) { + if (atadev->param.atavalid & ATA_FLAG_54_58) { heads = atadev->param.current_heads; sectors = atadev->param.current_sectors; - } - else { + } + else { heads = atadev->param.heads; sectors = atadev->param.sectors; - } - ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, + } + ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, (request->u.ata.lba / (sectors * heads))); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, + ATA_IDX_OUTB(ch, ATA_CYL_MSB, (request->u.ata.lba / (sectors * heads)) >> 8); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | (((request->u.ata.lba% (sectors * heads)) / sectors) & 0xf)); } else { - ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); - ATA_IDX_OUTB(ch, ATA_DRIVE, + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | atadev->unit | ((request->u.ata.lba >> 24) & 0x0f)); } } - /* issue command to controller */ - ATA_IDX_OUTB(ch, ATA_COMMAND, command); + /* issue command to controller */ + ATA_IDX_OUTB(ch, ATA_COMMAND, command); } return 0; diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 5cadc29fce8b..f31a449d595e 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -141,11 +141,11 @@ struct ata_connect_task { #define ATA_I82801FB_S1 0x26518086 #define ATA_I82801FB_R1 0x26528086 #define ATA_I82801FB_M 0x26538086 -#define ATA_I82801GB 0x27df8086 -#define ATA_I82801GB_S1 0x27c08086 -#define ATA_I82801GB_R1 0x27c38086 -#define ATA_I82801GB_AH 0x27c18086 -#define ATA_I82801GB_M 0x27c58086 +#define ATA_I82801GB 0x27df8086 +#define ATA_I82801GB_S1 0x27c08086 +#define ATA_I82801GB_R1 0x27c38086 +#define ATA_I82801GB_AH 0x27c18086 +#define ATA_I82801GB_M 0x27c58086 #define ATA_ITE_ID 0x1283 #define ATA_IT8212F 0x82121283 diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index e2bbf3d91819..4b2824f1ba53 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -58,10 +58,10 @@ __FBSDID("$FreeBSD$"); /* prototypes */ static void ata_raid_done(struct ata_request *request); static void ata_raid_config_changed(struct ar_softc *rdp, int writeback); -static int ata_raid_status(int array, struct raid_status *status); -static int ata_raid_create(struct raid_setup *setup); +static int ata_raid_status(struct ata_ioc_raid_config *config); +static int ata_raid_create(struct ata_ioc_raid_config *config); static int ata_raid_delete(int array); -static int ata_raid_addspare(int array, int spare); +static int ata_raid_addspare(struct ata_ioc_raid_config *config); static int ata_raid_rebuild(int array); static int ata_raid_read_metadata(device_t subdisk); static int ata_raid_write_metadata(struct ar_softc *rdp); @@ -184,29 +184,31 @@ ata_raid_attach(struct ar_softc *rdp, int writeback) } static int -ata_raid_ioctl(struct ata_cmd *iocmd) +ata_raid_ioctl(u_long cmd, caddr_t data) { + struct ata_ioc_raid_config *config = (struct ata_ioc_raid_config *)data; + int *lun = (int *)data; int error = EOPNOTSUPP; - switch (iocmd->cmd) { - case ATARAIDSTATUS: - error = ata_raid_status(iocmd->channel, &iocmd->u.raid_status); + switch (cmd) { + case IOCATARAIDSTATUS: + error = ata_raid_status(config); break; - case ATARAIDCREATE: - error = ata_raid_create(&iocmd->u.raid_setup); + case IOCATARAIDCREATE: + error = ata_raid_create(config); break; - case ATARAIDDELETE: - error = ata_raid_delete(iocmd->channel); + case IOCATARAIDDELETE: + error = ata_raid_delete(*lun); break; - case ATARAIDADDSPARE: - error = ata_raid_addspare(iocmd->channel, iocmd->u.raid_spare.disk); + case IOCATARAIDADDSPARE: + error = ata_raid_addspare(config); break; - case ATARAIDREBUILD: - error = ata_raid_rebuild(iocmd->channel); + case IOCATARAIDREBUILD: + error = ata_raid_rebuild(*lun); break; } return error; @@ -806,30 +808,30 @@ ata_raid_config_changed(struct ar_softc *rdp, int writeback) } static int -ata_raid_status(int array, struct raid_status *status) +ata_raid_status(struct ata_ioc_raid_config *config) { struct ar_softc *rdp; int i; - if (!(rdp = ata_raid_arrays[array])) + if (!(rdp = ata_raid_arrays[config->lun])) return ENXIO; - status->type = rdp->type; - status->total_disks = rdp->total_disks; + config->type = rdp->type; + config->total_disks = rdp->total_disks; for (i = 0; i < rdp->total_disks; i++ ) { if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].dev) - status->disks[i] = device_get_unit(rdp->disks[i].dev); + config->disks[i] = device_get_unit(rdp->disks[i].dev); else - status->disks[i] = -1; + config->disks[i] = -1; } - status->interleave = rdp->interleave; - status->status = rdp->status; - status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; + config->interleave = rdp->interleave; + config->status = rdp->status; + config->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; return 0; } static int -ata_raid_create(struct raid_setup *setup) +ata_raid_create(struct ata_ioc_raid_config *config) { struct ar_softc *rdp; device_t subdisk; @@ -849,14 +851,14 @@ ata_raid_create(struct raid_setup *setup) return ENOMEM; } - for (disk = 0; disk < setup->total_disks; disk++) { + for (disk = 0; disk < config->total_disks; disk++) { if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - setup->disks[disk]))) { + config->disks[disk]))) { struct ata_raid_subdisk *ars = device_get_softc(subdisk); /* is device already assigned to another array ? */ if (ars->raid) { - setup->disks[disk] = -1; + config->disks[disk] = -1; free(rdp, M_AR); return EBUSY; } @@ -930,18 +932,18 @@ ata_raid_create(struct raid_setup *setup) total_disks++; } else { - setup->disks[disk] = -1; + config->disks[disk] = -1; free(rdp, M_AR); return ENXIO; } } - if (total_disks != setup->total_disks) { + if (total_disks != config->total_disks) { free(rdp, M_AR); return ENODEV; } - switch (setup->type) { + switch (config->type) { case AR_T_JBOD: case AR_T_SPAN: case AR_T_RAID0: @@ -972,13 +974,13 @@ ata_raid_create(struct raid_setup *setup) free(rdp, M_AR); return EOPNOTSUPP; } - rdp->type = setup->type; + rdp->type = config->type; rdp->lun = array; if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 || rdp->type == AR_T_RAID5) { int bit = 0; - while (setup->interleave >>= 1) + while (config->interleave >>= 1) bit++; rdp->interleave = 1 << bit; } @@ -1038,9 +1040,9 @@ ata_raid_create(struct raid_setup *setup) rdp->status |= AR_S_READY; /* we are committed to this array, grap the subdisks */ - for (disk = 0; disk < setup->total_disks; disk++) { + for (disk = 0; disk < config->total_disks; disk++) { if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - setup->disks[disk]))) { + config->disks[disk]))) { struct ata_raid_subdisk *ars = device_get_softc(subdisk); ars->raid = rdp; @@ -1049,7 +1051,7 @@ ata_raid_create(struct raid_setup *setup) } ata_raid_attach(rdp, 1); ata_raid_arrays[array] = rdp; - setup->unit = array; + config->lun = array; return 0; } @@ -1089,13 +1091,13 @@ ata_raid_delete(int array) } static int -ata_raid_addspare(int array, int spare) +ata_raid_addspare(struct ata_ioc_raid_config *config) { struct ar_softc *rdp; device_t subdisk; int disk; - if (!(rdp = ata_raid_arrays[array])) + if (!(rdp = ata_raid_arrays[config->lun])) return ENXIO; if (!(rdp->status & AR_S_DEGRADED) || !(rdp->status & AR_S_READY)) return ENXIO; @@ -1111,7 +1113,8 @@ ata_raid_addspare(int array, int spare) (AR_DF_PRESENT | AR_DF_ONLINE)) && rdp->disks[disk].dev) continue; - if ((subdisk = devclass_get_device(ata_raid_sub_devclass, spare ))){ + if ((subdisk = devclass_get_device(ata_raid_sub_devclass, + config->disks[0] ))) { struct ata_raid_subdisk *ars = device_get_softc(subdisk); if (ars->raid) @@ -3136,7 +3139,7 @@ ata_raid_module_event_handler(module_t mod, int what, void *arg) ata_raid_print_meta(rdp); ata_raid_attach(rdp, 0); } - ata_ioctl_func = ata_raid_ioctl; + ata_raid_ioctl_func = ata_raid_ioctl; return 0; case MOD_UNLOAD: @@ -3152,7 +3155,7 @@ ata_raid_module_event_handler(module_t mod, int what, void *arg) #if 0 free(ata_raid_arrays, M_AR); #endif - ata_ioctl_func = NULL; + ata_raid_ioctl_func = NULL; return 0; default: diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index c6e2309ad74c..34938373a73d 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -413,7 +413,7 @@ 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")); - ata_controlcmd(softc->atadev[tid]->dev, ATA_ATAPI_RESET, 0, 0, 0); + ata_controlcmd(softc->atadev[tid]->dev, ATA_DEVICE_RESET, 0, 0, 0); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return; diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 48df3bf50717..61c0517232a4 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include /* prototypes */ @@ -676,7 +675,7 @@ acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, int fflag, struct break; default: - error = ENOTTY; + error = ata_device_ioctl(dev, cmd, addr); } return error; } diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 98d407223532..00c53ac39d5f 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); static disk_open_t afd_open; static disk_close_t afd_close; static disk_strategy_t afd_strategy; +static disk_ioctl_t afd_ioctl; static int afd_sense(device_t); static void afd_describe(device_t); static void afd_done(struct ata_request *); @@ -103,6 +104,7 @@ afd_attach(device_t dev) fdp->disk->d_open = afd_open; fdp->disk->d_close = afd_close; fdp->disk->d_strategy = afd_strategy; + fdp->disk->d_ioctl = afd_ioctl; fdp->disk->d_name = "afd"; fdp->disk->d_drv1 = dev; if (ch->dma) @@ -281,6 +283,12 @@ afd_done(struct ata_request *request) ata_free_request(request); } +static int +afd_ioctl(struct disk *disk, u_long cmd, void *data, int flag,struct thread *td) +{ + return ata_device_ioctl(disk->d_drv1, cmd, data); +} + static int afd_sense(device_t dev) { diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index 8ba9e55a44bb..b06ce47dea94 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -263,7 +263,7 @@ ast_close(struct cdev *cdev, int flags, int fmt, struct thread *td) } static int -ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread *td) +ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int flag, struct thread *td) { device_t dev = cdev->si_drv1; struct ast_softc *stp = device_get_ivars(dev); @@ -272,7 +272,7 @@ ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread * switch (cmd) { case MTIOCGET: { - struct mtget *g = (struct mtget *) addr; + struct mtget *g = (struct mtget *) data; bzero(g, sizeof(struct mtget)); g->mt_type = 7; @@ -291,7 +291,7 @@ ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread * case MTIOCTOP: { int i; - struct mtop *mt = (struct mtop *)addr; + struct mtop *mt = (struct mtop *)data; switch ((int16_t) (mt->mt_op)) { @@ -353,7 +353,7 @@ ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread * if ((error = ast_read_position(dev, 0, &position))) break; - *(u_int32_t *)addr = position.tape; + *(u_int32_t *)data = position.tape; } break; @@ -363,20 +363,20 @@ ast_ioctl(struct cdev *cdev, u_long cmd, caddr_t addr, int flag, struct thread * if ((error = ast_read_position(dev, 1, &position))) break; - *(u_int32_t *)addr = position.tape; + *(u_int32_t *)data = position.tape; } break; case MTIOCSLOCATE: - error = ast_locate(dev, 0, *(u_int32_t *)addr); + error = ast_locate(dev, 0, *(u_int32_t *)data); break; case MTIOCHLOCATE: - error = ast_locate(dev, 1, *(u_int32_t *)addr); + error = ast_locate(dev, 1, *(u_int32_t *)data); break; default: - error = ENOTTY; + error = ata_device_ioctl(dev, cmd, data); } return error; } diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 57a6f4fc2e36..6ac187b2eea6 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -35,384 +35,373 @@ /* ATA/ATAPI device parameters */ struct ata_params { -/*000*/ u_int16_t config; /* configuration info */ -#define ATA_PROTO_MASK 0x8003 -#define ATA_PROTO_ATAPI 0x8000 -#define ATA_PROTO_ATAPI_12 0x8000 -#define ATA_PROTO_ATAPI_16 0x8001 -#define ATA_ATAPI_TYPE_MASK 0x1f00 -#define ATA_ATAPI_TYPE_DIRECT 0x0000 /* disk/floppy */ -#define ATA_ATAPI_TYPE_TAPE 0x0100 /* streaming tape */ -#define ATA_ATAPI_TYPE_CDROM 0x0500 /* CD-ROM device */ -#define ATA_ATAPI_TYPE_OPTICAL 0x0700 /* optical disk */ -#define ATA_DRQ_MASK 0x0060 -#define ATA_DRQ_SLOW 0x0000 /* cpu 3 ms delay */ -#define ATA_DRQ_INTR 0x0020 /* interrupt 10 ms delay */ -#define ATA_DRQ_FAST 0x0040 /* accel 50 us delay */ +/*000*/ u_int16_t config; /* configuration info */ +#define ATA_PROTO_MASK 0x8003 +#define ATA_PROTO_ATAPI 0x8000 +#define ATA_PROTO_ATAPI_12 0x8000 +#define ATA_PROTO_ATAPI_16 0x8001 +#define ATA_ATAPI_TYPE_MASK 0x1f00 +#define ATA_ATAPI_TYPE_DIRECT 0x0000 /* disk/floppy */ +#define ATA_ATAPI_TYPE_TAPE 0x0100 /* streaming tape */ +#define ATA_ATAPI_TYPE_CDROM 0x0500 /* CD-ROM device */ +#define ATA_ATAPI_TYPE_OPTICAL 0x0700 /* optical disk */ +#define ATA_DRQ_MASK 0x0060 +#define ATA_DRQ_SLOW 0x0000 /* cpu 3 ms delay */ +#define ATA_DRQ_INTR 0x0020 /* interrupt 10 ms delay */ +#define ATA_DRQ_FAST 0x0040 /* accel 50 us delay */ -/*001*/ u_int16_t cylinders; /* # of cylinders */ - u_int16_t reserved2; -/*003*/ u_int16_t heads; /* # heads */ - u_int16_t obsolete4; - u_int16_t obsolete5; -/*006*/ u_int16_t sectors; /* # sectors/track */ -/*007*/ u_int16_t vendor7[3]; -/*010*/ u_int8_t serial[20]; /* serial number */ -/*020*/ u_int16_t retired20; - u_int16_t retired21; - u_int16_t obsolete22; -/*023*/ u_int8_t revision[8]; /* firmware revision */ -/*027*/ u_int8_t model[40]; /* model name */ -/*047*/ u_int16_t sectors_intr; /* sectors per interrupt */ -/*048*/ u_int16_t usedmovsd; /* double word read/write? */ -/*049*/ u_int16_t capabilities1; -#define ATA_SUPPORT_DMA 0x0100 -#define ATA_SUPPORT_LBA 0x0200 -#define ATA_SUPPORT_OVERLAP 0x4000 +/*001*/ u_int16_t cylinders; /* # of cylinders */ + u_int16_t reserved2; +/*003*/ u_int16_t heads; /* # heads */ + u_int16_t obsolete4; + u_int16_t obsolete5; +/*006*/ u_int16_t sectors; /* # sectors/track */ +/*007*/ u_int16_t vendor7[3]; +/*010*/ u_int8_t serial[20]; /* serial number */ +/*020*/ u_int16_t retired20; + u_int16_t retired21; + u_int16_t obsolete22; +/*023*/ u_int8_t revision[8]; /* firmware revision */ +/*027*/ u_int8_t model[40]; /* model name */ +/*047*/ u_int16_t sectors_intr; /* sectors per interrupt */ +/*048*/ u_int16_t usedmovsd; /* double word read/write? */ +/*049*/ u_int16_t capabilities1; +#define ATA_SUPPORT_DMA 0x0100 +#define ATA_SUPPORT_LBA 0x0200 +#define ATA_SUPPORT_OVERLAP 0x4000 -/*050*/ u_int16_t capabilities2; -/*051*/ u_int16_t retired_piomode; /* PIO modes 0-2 */ -#define ATA_RETIRED_PIO_MASK 0x0300 +/*050*/ u_int16_t capabilities2; +/*051*/ u_int16_t retired_piomode; /* PIO modes 0-2 */ +#define ATA_RETIRED_PIO_MASK 0x0300 -/*052*/ u_int16_t retired_dmamode; /* DMA modes */ -#define ATA_RETIRED_DMA_MASK 0x0003 +/*052*/ u_int16_t retired_dmamode; /* DMA modes */ +#define ATA_RETIRED_DMA_MASK 0x0003 -/*053*/ u_int16_t atavalid; /* fields valid */ -#define ATA_FLAG_54_58 0x0001 /* words 54-58 valid */ -#define ATA_FLAG_64_70 0x0002 /* words 64-70 valid */ -#define ATA_FLAG_88 0x0004 /* word 88 valid */ +/*053*/ u_int16_t atavalid; /* fields valid */ +#define ATA_FLAG_54_58 0x0001 /* words 54-58 valid */ +#define ATA_FLAG_64_70 0x0002 /* words 64-70 valid */ +#define ATA_FLAG_88 0x0004 /* word 88 valid */ -/*054*/ u_int16_t current_cylinders; -/*055*/ u_int16_t current_heads; -/*056*/ u_int16_t current_sectors; -/*057*/ u_int16_t current_size_1; -/*058*/ u_int16_t current_size_2; -/*059*/ u_int16_t multi; -#define ATA_MULTI_VALID 0x0100 +/*054*/ u_int16_t current_cylinders; +/*055*/ u_int16_t current_heads; +/*056*/ u_int16_t current_sectors; +/*057*/ u_int16_t current_size_1; +/*058*/ u_int16_t current_size_2; +/*059*/ u_int16_t multi; +#define ATA_MULTI_VALID 0x0100 -/*060*/ u_int16_t lba_size_1; - u_int16_t lba_size_2; - u_int16_t obsolete62; -/*063*/ u_int16_t mwdmamodes; /* multiword DMA modes */ -/*064*/ u_int16_t apiomodes; /* advanced PIO modes */ +/*060*/ u_int16_t lba_size_1; + u_int16_t lba_size_2; + u_int16_t obsolete62; +/*063*/ u_int16_t mwdmamodes; /* multiword DMA modes */ +/*064*/ u_int16_t apiomodes; /* advanced PIO modes */ -/*065*/ u_int16_t mwdmamin; /* min. M/W DMA time/word ns */ -/*066*/ u_int16_t mwdmarec; /* rec. M/W DMA time ns */ -/*067*/ u_int16_t pioblind; /* min. PIO cycle w/o flow */ -/*068*/ u_int16_t pioiordy; /* min. PIO cycle IORDY flow */ - u_int16_t reserved69; - u_int16_t reserved70; -/*071*/ u_int16_t rlsovlap; /* rel time (us) for overlap */ -/*072*/ u_int16_t rlsservice; /* rel time (us) for service */ - u_int16_t reserved73; - u_int16_t reserved74; -/*075*/ u_int16_t queue; -#define ATA_QUEUE_LEN(x) ((x) & 0x001f) +/*065*/ u_int16_t mwdmamin; /* min. M/W DMA time/word ns */ +/*066*/ u_int16_t mwdmarec; /* rec. M/W DMA time ns */ +/*067*/ u_int16_t pioblind; /* min. PIO cycle w/o flow */ +/*068*/ u_int16_t pioiordy; /* min. PIO cycle IORDY flow */ + u_int16_t reserved69; + u_int16_t reserved70; +/*071*/ u_int16_t rlsovlap; /* rel time (us) for overlap */ +/*072*/ u_int16_t rlsservice; /* rel time (us) for service */ + u_int16_t reserved73; + u_int16_t reserved74; +/*075*/ u_int16_t queue; +#define ATA_QUEUE_LEN(x) ((x) & 0x001f) - u_int16_t satacapabilities; -#define ATA_SATA_GEN1 0x0002 -#define ATA_SATA_GEN2 0x0004 -#define ATA_SUPPORT_NCQ 0x0100 -#define ATA_SUPPORT_IFPWRMNGTRCV 0x0200 + u_int16_t satacapabilities; +#define ATA_SATA_GEN1 0x0002 +#define ATA_SATA_GEN2 0x0004 +#define ATA_SUPPORT_NCQ 0x0100 +#define ATA_SUPPORT_IFPWRMNGTRCV 0x0200 - u_int16_t reserved77; - u_int16_t satasupport; -#define ATA_SUPPORT_NONZERO 0x0002 -#define ATA_SUPPORT_AUTOACTIVATE 0x0004 -#define ATA_SUPPORT_IFPWRMNGT 0x0008 -#define ATA_SUPPORT_INORDERDATA 0x0010 - u_int16_t sataenabled; + u_int16_t reserved77; + u_int16_t satasupport; +#define ATA_SUPPORT_NONZERO 0x0002 +#define ATA_SUPPORT_AUTOACTIVATE 0x0004 +#define ATA_SUPPORT_IFPWRMNGT 0x0008 +#define ATA_SUPPORT_INORDERDATA 0x0010 + u_int16_t sataenabled; -/*080*/ u_int16_t version_major; -/*081*/ u_int16_t version_minor; +/*080*/ u_int16_t version_major; +/*081*/ u_int16_t version_minor; struct { -/*082/085*/ u_int16_t command1; -#define ATA_SUPPORT_SMART 0x0001 -#define ATA_SUPPORT_SECURITY 0x0002 -#define ATA_SUPPORT_REMOVABLE 0x0004 -#define ATA_SUPPORT_POWERMGT 0x0008 -#define ATA_SUPPORT_PACKET 0x0010 -#define ATA_SUPPORT_WRITECACHE 0x0020 -#define ATA_SUPPORT_LOOKAHEAD 0x0040 -#define ATA_SUPPORT_RELEASEIRQ 0x0080 -#define ATA_SUPPORT_SERVICEIRQ 0x0100 -#define ATA_SUPPORT_RESET 0x0200 -#define ATA_SUPPORT_PROTECTED 0x0400 -#define ATA_SUPPORT_WRITEBUFFER 0x1000 -#define ATA_SUPPORT_READBUFFER 0x2000 -#define ATA_SUPPORT_NOP 0x4000 +/*082/085*/ u_int16_t command1; +#define ATA_SUPPORT_SMART 0x0001 +#define ATA_SUPPORT_SECURITY 0x0002 +#define ATA_SUPPORT_REMOVABLE 0x0004 +#define ATA_SUPPORT_POWERMGT 0x0008 +#define ATA_SUPPORT_PACKET 0x0010 +#define ATA_SUPPORT_WRITECACHE 0x0020 +#define ATA_SUPPORT_LOOKAHEAD 0x0040 +#define ATA_SUPPORT_RELEASEIRQ 0x0080 +#define ATA_SUPPORT_SERVICEIRQ 0x0100 +#define ATA_SUPPORT_RESET 0x0200 +#define ATA_SUPPORT_PROTECTED 0x0400 +#define ATA_SUPPORT_WRITEBUFFER 0x1000 +#define ATA_SUPPORT_READBUFFER 0x2000 +#define ATA_SUPPORT_NOP 0x4000 -/*083/086*/ u_int16_t command2; -#define ATA_SUPPORT_MICROCODE 0x0001 -#define ATA_SUPPORT_QUEUED 0x0002 -#define ATA_SUPPORT_CFA 0x0004 -#define ATA_SUPPORT_APM 0x0008 -#define ATA_SUPPORT_NOTIFY 0x0010 -#define ATA_SUPPORT_STANDBY 0x0020 -#define ATA_SUPPORT_SPINUP 0x0040 -#define ATA_SUPPORT_MAXSECURITY 0x0100 -#define ATA_SUPPORT_AUTOACOUSTIC 0x0200 -#define ATA_SUPPORT_ADDRESS48 0x0400 -#define ATA_SUPPORT_OVERLAY 0x0800 -#define ATA_SUPPORT_FLUSHCACHE 0x1000 -#define ATA_SUPPORT_FLUSHCACHE48 0x2000 +/*083/086*/ u_int16_t command2; +#define ATA_SUPPORT_MICROCODE 0x0001 +#define ATA_SUPPORT_QUEUED 0x0002 +#define ATA_SUPPORT_CFA 0x0004 +#define ATA_SUPPORT_APM 0x0008 +#define ATA_SUPPORT_NOTIFY 0x0010 +#define ATA_SUPPORT_STANDBY 0x0020 +#define ATA_SUPPORT_SPINUP 0x0040 +#define ATA_SUPPORT_MAXSECURITY 0x0100 +#define ATA_SUPPORT_AUTOACOUSTIC 0x0200 +#define ATA_SUPPORT_ADDRESS48 0x0400 +#define ATA_SUPPORT_OVERLAY 0x0800 +#define ATA_SUPPORT_FLUSHCACHE 0x1000 +#define ATA_SUPPORT_FLUSHCACHE48 0x2000 -/*084/087*/ u_int16_t extension; +/*084/087*/ u_int16_t extension; } __packed support, enabled; -/*088*/ u_int16_t udmamodes; /* UltraDMA modes */ -/*089*/ u_int16_t erase_time; -/*090*/ u_int16_t enhanced_erase_time; -/*091*/ u_int16_t apm_value; -/*092*/ u_int16_t master_passwd_revision; -/*093*/ u_int16_t hwres; -#define ATA_CABLE_ID 0x2000 +/*088*/ u_int16_t udmamodes; /* UltraDMA modes */ +/*089*/ u_int16_t erase_time; +/*090*/ u_int16_t enhanced_erase_time; +/*091*/ u_int16_t apm_value; +/*092*/ u_int16_t master_passwd_revision; +/*093*/ u_int16_t hwres; +#define ATA_CABLE_ID 0x2000 -/*094*/ u_int16_t acoustic; -#define ATA_ACOUSTIC_CURRENT(x) ((x) & 0x00ff) -#define ATA_ACOUSTIC_VENDOR(x) (((x) & 0xff00) >> 8) +/*094*/ u_int16_t acoustic; +#define ATA_ACOUSTIC_CURRENT(x) ((x) & 0x00ff) +#define ATA_ACOUSTIC_VENDOR(x) (((x) & 0xff00) >> 8) -/*095*/ u_int16_t stream_min_req_size; -/*096*/ u_int16_t stream_transfer_time; -/*097*/ u_int16_t stream_access_latency; -/*098*/ u_int32_t stream_granularity; -/*100*/ u_int16_t lba_size48_1; - u_int16_t lba_size48_2; - u_int16_t lba_size48_3; - u_int16_t lba_size48_4; - u_int16_t reserved104[23]; -/*127*/ u_int16_t removable_status; -/*128*/ u_int16_t security_status; - u_int16_t reserved129[31]; -/*160*/ u_int16_t cfa_powermode1; - u_int16_t reserved161[15]; -/*176*/ u_int16_t media_serial[30]; - u_int16_t reserved206[49]; -/*255*/ u_int16_t integrity; +/*095*/ u_int16_t stream_min_req_size; +/*096*/ u_int16_t stream_transfer_time; +/*097*/ u_int16_t stream_access_latency; +/*098*/ u_int32_t stream_granularity; +/*100*/ u_int16_t lba_size48_1; + u_int16_t lba_size48_2; + u_int16_t lba_size48_3; + u_int16_t lba_size48_4; + u_int16_t reserved104[23]; +/*127*/ u_int16_t removable_status; +/*128*/ u_int16_t security_status; + u_int16_t reserved129[31]; +/*160*/ u_int16_t cfa_powermode1; + u_int16_t reserved161[15]; +/*176*/ u_int16_t media_serial[30]; + u_int16_t reserved206[49]; +/*255*/ u_int16_t integrity; } __packed; + /* ATA transfer modes */ -#define ATA_MODE_MASK 0x0f -#define ATA_DMA_MASK 0xf0 -#define ATA_PIO 0x00 -#define ATA_PIO0 0x08 -#define ATA_PIO1 0x09 -#define ATA_PIO2 0x0a -#define ATA_PIO3 0x0b -#define ATA_PIO4 0x0c -#define ATA_PIO_MAX 0x0f -#define ATA_DMA 0x10 -#define ATA_WDMA0 0x20 -#define ATA_WDMA1 0x21 -#define ATA_WDMA2 0x22 -#define ATA_UDMA0 0x40 -#define ATA_UDMA1 0x41 -#define ATA_UDMA2 0x42 -#define ATA_UDMA3 0x43 -#define ATA_UDMA4 0x44 -#define ATA_UDMA5 0x45 -#define ATA_UDMA6 0x46 -#define ATA_SA150 0x47 -#define ATA_DMA_MAX 0x4f +#define ATA_MODE_MASK 0x0f +#define ATA_DMA_MASK 0xf0 +#define ATA_PIO 0x00 +#define ATA_PIO0 0x08 +#define ATA_PIO1 0x09 +#define ATA_PIO2 0x0a +#define ATA_PIO3 0x0b +#define ATA_PIO4 0x0c +#define ATA_PIO_MAX 0x0f +#define ATA_DMA 0x10 +#define ATA_WDMA0 0x20 +#define ATA_WDMA1 0x21 +#define ATA_WDMA2 0x22 +#define ATA_UDMA0 0x40 +#define ATA_UDMA1 0x41 +#define ATA_UDMA2 0x42 +#define ATA_UDMA3 0x43 +#define ATA_UDMA4 0x44 +#define ATA_UDMA5 0x45 +#define ATA_UDMA6 0x46 +#define ATA_SA150 0x47 +#define ATA_DMA_MAX 0x4f + /* ATA commands */ -#define ATA_NOP 0x00 /* NOP command */ -#define ATA_NF_FLUSHQUEUE 0x00 /* flush queued cmd's */ -#define ATA_NF_AUTOPOLL 0x01 /* start autopoll function */ -#define ATA_ATAPI_RESET 0x08 /* reset ATAPI device */ -#define ATA_READ 0x20 /* read command */ -#define ATA_READ48 0x24 /* read command */ -#define ATA_READ_DMA48 0x25 /* read w/DMA command */ -#define ATA_READ_DMA_QUEUED48 0x26 /* read w/DMA QUEUED command */ -#define ATA_READ_MUL48 0x29 /* read multi command */ -#define ATA_WRITE 0x30 /* write command */ -#define ATA_WRITE48 0x34 /* write command */ -#define ATA_WRITE_DMA48 0x35 /* write w/DMA command */ -#define ATA_WRITE_DMA_QUEUED48 0x36 /* write w/DMA QUEUED command */ -#define ATA_WRITE_MUL48 0x39 /* write multi command */ -#define ATA_PACKET_CMD 0xa0 /* packet command */ -#define ATA_ATAPI_IDENTIFY 0xa1 /* get ATAPI params*/ -#define ATA_SERVICE 0xa2 /* service command */ -#define ATA_READ_MUL 0xc4 /* read multi command */ -#define ATA_WRITE_MUL 0xc5 /* write multi command */ -#define ATA_SET_MULTI 0xc6 /* set multi size command */ -#define ATA_READ_DMA_QUEUED 0xc7 /* read w/DMA QUEUED command */ -#define ATA_READ_DMA 0xc8 /* read w/DMA command */ -#define ATA_WRITE_DMA 0xca /* write w/DMA command */ -#define ATA_WRITE_DMA_QUEUED 0xcc /* write w/DMA QUEUED command */ -#define ATA_SLEEP 0xe6 /* sleep command */ -#define ATA_FLUSHCACHE 0xe7 /* flush cache to disk */ -#define ATA_FLUSHCACHE48 0xea /* flush cache to disk */ -#define ATA_ATA_IDENTIFY 0xec /* get ATA params */ -#define ATA_SETFEATURES 0xef /* features command */ -#define ATA_SF_SETXFER 0x03 /* set transfer mode */ -#define ATA_SF_ENAB_WCACHE 0x02 /* enable write cache */ -#define ATA_SF_DIS_WCACHE 0x82 /* disable write cache */ -#define ATA_SF_ENAB_RCACHE 0xaa /* enable readahead cache */ -#define ATA_SF_DIS_RCACHE 0x55 /* disable readahead cache */ -#define ATA_SF_ENAB_RELIRQ 0x5d /* enable release interrupt */ -#define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */ -#define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */ -#define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */ +#define ATA_NOP 0x00 /* NOP */ +#define ATA_NF_FLUSHQUEUE 0x00 /* flush queued cmd's */ +#define ATA_NF_AUTOPOLL 0x01 /* start autopoll function */ +#define ATA_DEVICE_RESET 0x08 /* reset device */ +#define ATA_READ 0x20 /* read */ +#define ATA_READ48 0x24 /* read 48bit LBA */ +#define ATA_READ_DMA48 0x25 /* read DMA 48bit LBA */ +#define ATA_READ_DMA_QUEUED48 0x26 /* read DMA QUEUED 48bit LBA */ +#define ATA_READ_MUL48 0x29 /* read multi 48bit LBA */ +#define ATA_WRITE 0x30 /* write */ +#define ATA_WRITE48 0x34 /* write 48bit LBA */ +#define ATA_WRITE_DMA48 0x35 /* write DMA 48bit LBA */ +#define ATA_WRITE_DMA_QUEUED48 0x36 /* write DMA QUEUED 48bit LBA*/ +#define ATA_WRITE_MUL48 0x39 /* write multi 48bit LBA */ +#define ATA_READ_FPDMA_QUEUED 0x60 /* read DMA NCQ */ +#define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */ +#define ATA_SEEK 0x70 /* seek */ +#define ATA_PACKET_CMD 0xa0 /* packet command */ +#define ATA_ATAPI_IDENTIFY 0xa1 /* get ATAPI params*/ +#define ATA_SERVICE 0xa2 /* service command */ +#define ATA_CFA_ERASE 0xc0 /* CFA erase */ +#define ATA_READ_MUL 0xc4 /* read multi */ +#define ATA_WRITE_MUL 0xc5 /* write multi */ +#define ATA_SET_MULTI 0xc6 /* set multi size */ +#define ATA_READ_DMA_QUEUED 0xc7 /* read DMA QUEUED */ +#define ATA_READ_DMA 0xc8 /* read DMA */ +#define ATA_WRITE_DMA 0xca /* write DMA */ +#define ATA_WRITE_DMA_QUEUED 0xcc /* write DMA QUEUED */ +#define ATA_STANDBY_IMMEDIATE 0xe0 /* standby immediate */ +#define ATA_IDLE_IMMEDIATE 0xe1 /* idle immediate */ +#define ATA_STANDBY_CMD 0xe2 /* standby */ +#define ATA_IDLE_CMD 0xe3 /* idle */ +#define ATA_READ_BUFFER 0xe4 /* read buffer */ +#define ATA_SLEEP 0xe6 /* sleep */ +#define ATA_FLUSHCACHE 0xe7 /* flush cache to disk */ +#define ATA_FLUSHCACHE48 0xea /* flush cache to disk */ +#define ATA_ATA_IDENTIFY 0xec /* get ATA params */ +#define ATA_SETFEATURES 0xef /* features command */ +#define ATA_SF_SETXFER 0x03 /* set transfer mode */ +#define ATA_SF_ENAB_WCACHE 0x02 /* enable write cache */ +#define ATA_SF_DIS_WCACHE 0x82 /* disable write cache */ +#define ATA_SF_ENAB_RCACHE 0xaa /* enable readahead cache */ +#define ATA_SF_DIS_RCACHE 0x55 /* disable readahead cache */ +#define ATA_SF_ENAB_RELIRQ 0x5d /* enable release interrupt */ +#define ATA_SF_DIS_RELIRQ 0xdd /* disable release interrupt */ +#define ATA_SF_ENAB_SRVIRQ 0x5e /* enable service interrupt */ +#define ATA_SF_DIS_SRVIRQ 0xde /* disable service interrupt */ +#define ATA_SECURITY_FREEE_LOCK 0xf5 /* freeze security config */ +#define ATA_READ_NATIVE_MAX_ADDDRESS 0xf8 /* read native max address */ +#define ATA_SET_MAX_ADDRESS 0xf9 /* set max address */ + /* ATAPI commands */ -#define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */ -#define ATAPI_REZERO 0x01 /* rewind */ -#define ATAPI_REQUEST_SENSE 0x03 /* get sense data */ -#define ATAPI_FORMAT 0x04 /* format unit */ -#define ATAPI_READ 0x08 /* read data */ -#define ATAPI_WRITE 0x0a /* write data */ -#define ATAPI_WEOF 0x10 /* write filemark */ -#define ATAPI_WF_WRITE 0x01 -#define ATAPI_SPACE 0x11 /* space command */ -#define ATAPI_SP_FM 0x01 -#define ATAPI_SP_EOD 0x03 -#define ATAPI_MODE_SELECT 0x15 /* mode select */ -#define ATAPI_ERASE 0x19 /* erase */ -#define ATAPI_MODE_SENSE 0x1a /* mode sense */ -#define ATAPI_START_STOP 0x1b /* start/stop unit */ -#define ATAPI_SS_LOAD 0x01 -#define ATAPI_SS_RETENSION 0x02 -#define ATAPI_SS_EJECT 0x04 -#define ATAPI_PREVENT_ALLOW 0x1e /* media removal */ -#define ATAPI_READ_FORMAT_CAPACITIES 0x23 /* get format capacities */ -#define ATAPI_READ_CAPACITY 0x25 /* get volume capacity */ -#define ATAPI_READ_BIG 0x28 /* read data */ -#define ATAPI_WRITE_BIG 0x2a /* write data */ -#define ATAPI_LOCATE 0x2b /* locate to position */ -#define ATAPI_READ_POSITION 0x34 /* read position */ -#define ATAPI_SYNCHRONIZE_CACHE 0x35 /* flush buf, close channel */ -#define ATAPI_WRITE_BUFFER 0x3b /* write device buffer */ -#define ATAPI_READ_BUFFER 0x3c /* read device buffer */ -#define ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */ -#define ATAPI_READ_TOC 0x43 /* get table of contents */ -#define ATAPI_PLAY_10 0x45 /* play by lba */ -#define ATAPI_PLAY_MSF 0x47 /* play by MSF address */ -#define ATAPI_PLAY_TRACK 0x48 /* play by track number */ -#define ATAPI_PAUSE 0x4b /* pause audio operation */ -#define ATAPI_READ_DISK_INFO 0x51 /* get disk info structure */ -#define ATAPI_READ_TRACK_INFO 0x52 /* get track info structure */ -#define ATAPI_RESERVE_TRACK 0x53 /* reserve track */ -#define ATAPI_SEND_OPC_INFO 0x54 /* send OPC structurek */ -#define ATAPI_MODE_SELECT_BIG 0x55 /* set device parameters */ -#define ATAPI_REPAIR_TRACK 0x58 /* repair track */ -#define ATAPI_READ_MASTER_CUE 0x59 /* read master CUE info */ -#define ATAPI_MODE_SENSE_BIG 0x5a /* get device parameters */ -#define ATAPI_CLOSE_TRACK 0x5b /* close track/session */ -#define ATAPI_READ_BUFFER_CAPACITY 0x5c /* get buffer capicity */ -#define ATAPI_SEND_CUE_SHEET 0x5d /* send CUE sheet */ -#define ATAPI_BLANK 0xa1 /* blank the media */ -#define ATAPI_SEND_KEY 0xa3 /* send DVD key structure */ -#define ATAPI_REPORT_KEY 0xa4 /* get DVD key structure */ -#define ATAPI_PLAY_12 0xa5 /* play by lba */ -#define ATAPI_LOAD_UNLOAD 0xa6 /* changer control command */ -#define ATAPI_READ_STRUCTURE 0xad /* get DVD structure */ -#define ATAPI_PLAY_CD 0xb4 /* universal play command */ -#define ATAPI_SET_SPEED 0xbb /* set drive speed */ -#define ATAPI_MECH_STATUS 0xbd /* get changer status */ -#define ATAPI_READ_CD 0xbe /* read data */ -#define ATAPI_POLL_DSC 0xff /* poll DSC status bit */ +#define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */ +#define ATAPI_REZERO 0x01 /* rewind */ +#define ATAPI_REQUEST_SENSE 0x03 /* get sense data */ +#define ATAPI_FORMAT 0x04 /* format unit */ +#define ATAPI_READ 0x08 /* read data */ +#define ATAPI_WRITE 0x0a /* write data */ +#define ATAPI_WEOF 0x10 /* write filemark */ +#define ATAPI_WF_WRITE 0x01 +#define ATAPI_SPACE 0x11 /* space command */ +#define ATAPI_SP_FM 0x01 +#define ATAPI_SP_EOD 0x03 +#define ATAPI_MODE_SELECT 0x15 /* mode select */ +#define ATAPI_ERASE 0x19 /* erase */ +#define ATAPI_MODE_SENSE 0x1a /* mode sense */ +#define ATAPI_START_STOP 0x1b /* start/stop unit */ +#define ATAPI_SS_LOAD 0x01 +#define ATAPI_SS_RETENSION 0x02 +#define ATAPI_SS_EJECT 0x04 +#define ATAPI_PREVENT_ALLOW 0x1e /* media removal */ +#define ATAPI_READ_FORMAT_CAPACITIES 0x23 /* get format capacities */ +#define ATAPI_READ_CAPACITY 0x25 /* get volume capacity */ +#define ATAPI_READ_BIG 0x28 /* read data */ +#define ATAPI_WRITE_BIG 0x2a /* write data */ +#define ATAPI_LOCATE 0x2b /* locate to position */ +#define ATAPI_READ_POSITION 0x34 /* read position */ +#define ATAPI_SYNCHRONIZE_CACHE 0x35 /* flush buf, close channel */ +#define ATAPI_WRITE_BUFFER 0x3b /* write device buffer */ +#define ATAPI_READ_BUFFER 0x3c /* read device buffer */ +#define ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */ +#define ATAPI_READ_TOC 0x43 /* get table of contents */ +#define ATAPI_PLAY_10 0x45 /* play by lba */ +#define ATAPI_PLAY_MSF 0x47 /* play by MSF address */ +#define ATAPI_PLAY_TRACK 0x48 /* play by track number */ +#define ATAPI_PAUSE 0x4b /* pause audio operation */ +#define ATAPI_READ_DISK_INFO 0x51 /* get disk info structure */ +#define ATAPI_READ_TRACK_INFO 0x52 /* get track info structure */ +#define ATAPI_RESERVE_TRACK 0x53 /* reserve track */ +#define ATAPI_SEND_OPC_INFO 0x54 /* send OPC structurek */ +#define ATAPI_MODE_SELECT_BIG 0x55 /* set device parameters */ +#define ATAPI_REPAIR_TRACK 0x58 /* repair track */ +#define ATAPI_READ_MASTER_CUE 0x59 /* read master CUE info */ +#define ATAPI_MODE_SENSE_BIG 0x5a /* get device parameters */ +#define ATAPI_CLOSE_TRACK 0x5b /* close track/session */ +#define ATAPI_READ_BUFFER_CAPACITY 0x5c /* get buffer capicity */ +#define ATAPI_SEND_CUE_SHEET 0x5d /* send CUE sheet */ +#define ATAPI_BLANK 0xa1 /* blank the media */ +#define ATAPI_SEND_KEY 0xa3 /* send DVD key structure */ +#define ATAPI_REPORT_KEY 0xa4 /* get DVD key structure */ +#define ATAPI_PLAY_12 0xa5 /* play by lba */ +#define ATAPI_LOAD_UNLOAD 0xa6 /* changer control command */ +#define ATAPI_READ_STRUCTURE 0xad /* get DVD structure */ +#define ATAPI_PLAY_CD 0xb4 /* universal play command */ +#define ATAPI_SET_SPEED 0xbb /* set drive speed */ +#define ATAPI_MECH_STATUS 0xbd /* get changer status */ +#define ATAPI_READ_CD 0xbe /* read data */ +#define ATAPI_POLL_DSC 0xff /* poll DSC status bit */ -struct ata_cmd { - int channel; - int device; - int cmd; -#define ATAGMAXCHANNEL 0x0101 -#define ATAGPARM 0x0102 -#define ATAGMODE 0x0103 -#define ATASMODE 0x0104 -#define ATAREQUEST 0x0108 -#define ATAREINIT 0x0110 -#define ATAATTACH 0x0111 -#define ATADETACH 0x0112 -#define ATARAIDCREATE 0x0120 -#define ATARAIDDELETE 0x0121 -#define ATARAIDSTATUS 0x0122 -#define ATARAIDADDSPARE 0x0123 -#define ATARAIDREBUILD 0x0124 -#define ATAENCSTAT 0x0130 - union { - int maxchan; - - struct { - int type[2]; - char name[2][32]; - struct ata_params params[2]; - } param; - - struct { - int mode[2]; - } mode; - - struct { - union { - struct { - u_int8_t command; - u_int8_t feature; - u_int64_t lba; - u_int16_t count; - } ata; - struct { - char ccb[16]; - } atapi; - } u; - caddr_t data; - int count; - int flags; -#define ATA_CMD_CONTROL 0x01 -#define ATA_CMD_READ 0x02 -#define ATA_CMD_WRITE 0x04 -#define ATA_CMD_ATAPI 0x08 - - int timeout; - int error; - } request; - - struct raid_setup { - int type; -#define AR_JBOD 0x01 -#define AR_SPAN 0x02 -#define AR_RAID0 0x04 -#define AR_RAID1 0x08 -#define AR_RAID01 0x10 -#define AR_RAID3 0x20 -#define AR_RAID4 0x40 -#define AR_RAID5 0x80 - - int total_disks; - int disks[16]; - int interleave; - int unit; - } raid_setup; - - struct raid_status { - int type; - int total_disks; - int disks[16]; - int interleave; - int status; -#define AR_READY 1 -#define AR_DEGRADED 2 -#define AR_REBUILDING 4 - - int progress; - } raid_status; - - struct { - int disk; - } raid_spare; - - struct { - int fan; - int temp; - int v05; - int v12; - } enclosure; - } u; +struct ata_ioc_devices { + int channel; + char name[2][32]; + struct ata_params params[2]; }; -#define IOCATA _IOWR('a', 1, struct ata_cmd) +/* pr channel ATA ioctl calls */ +#define IOCATAGMAXCHANNEL _IOR('a', 1, int) +#define IOCATAREINIT _IOW('a', 2, int) +#define IOCATAATTACH _IOW('a', 3, int) +#define IOCATADETACH _IOW('a', 4, int) +#define IOCATADEVICES _IOWR('a', 5, struct ata_ioc_devices) + +struct ata_ioc_request { + union { + struct { + u_int8_t command; + u_int8_t feature; + u_int64_t lba; + u_int16_t count; + } ata; + struct { + char ccb[16]; + } atapi; + } u; + caddr_t data; + int count; + int flags; +#define ATA_CMD_CONTROL 0x01 +#define ATA_CMD_READ 0x02 +#define ATA_CMD_WRITE 0x04 +#define ATA_CMD_ATAPI 0x08 + + int timeout; + int error; +}; + +/* pr device ATA ioctl calls */ +#define IOCATAREQUEST _IOWR('a', 100, struct ata_ioc_request) +#define IOCATAGPARM _IOR('a', 101, struct ata_params) +#define IOCATAGMODE _IOR('a', 102, int) +#define IOCATASMODE _IOW('a', 103, int) + + +struct ata_ioc_raid_config { + int lun; + int type; +#define AR_JBOD 0x0001 +#define AR_SPAN 0x0002 +#define AR_RAID0 0x0004 +#define AR_RAID1 0x0008 +#define AR_RAID01 0x0010 +#define AR_RAID3 0x0020 +#define AR_RAID4 0x0040 +#define AR_RAID5 0x0080 + + int interleave; + int status; +#define AR_READY 1 +#define AR_DEGRADED 2 +#define AR_REBUILDING 4 + + int progress; + int total_disks; + int disks[16]; +}; + +/* ATA RAID ioctl calls */ +#define IOCATARAIDCREATE _IOW('a', 200, struct ata_ioc_raid_config) +#define IOCATARAIDDELETE _IOW('a', 201, int) +#define IOCATARAIDSTATUS _IOR('a', 202, struct ata_ioc_raid_config) +#define IOCATARAIDADDSPARE _IOW('a', 203, struct ata_ioc_raid_config) +#define IOCATARAIDREBUILD _IOW('a', 204, int) #endif /* _SYS_ATA_H_ */