From 7c2b81b0e97e507aa2b3b3fac77056edcdf18669 Mon Sep 17 00:00:00 2001 From: mav Date: Thu, 4 Apr 2013 07:12:24 +0000 Subject: Remove all legacy ATA code parts, not used since options ATA_CAM enabled in most kernels before FreeBSD 9.0. Remove such modules and respective kernel options: atadisk, ataraid, atapicd, atapifd, atapist, atapicam. Remove the atacontrol utility and some man pages. Remove useless now options ATA_CAM. No objections: current@, stable@ MFC after: never --- sys/dev/ata/ata-all.c | 998 +----- sys/dev/ata/ata-all.h | 26 - sys/dev/ata/ata-cbus.c | 71 +- sys/dev/ata/ata-disk.c | 607 ---- sys/dev/ata/ata-disk.h | 47 - sys/dev/ata/ata-dma.c | 2 - sys/dev/ata/ata-lowlevel.c | 30 - sys/dev/ata/ata-pci.c | 18 - sys/dev/ata/ata-pci.h | 3 - sys/dev/ata/ata-queue.c | 639 ---- sys/dev/ata/ata-raid-ddf.h | 333 -- sys/dev/ata/ata-raid.c | 5462 ------------------------------- sys/dev/ata/ata-raid.h | 817 ----- sys/dev/ata/ata-sata.c | 4 - sys/dev/ata/ata_if.m | 18 - sys/dev/ata/atapi-cam.c | 919 ------ sys/dev/ata/atapi-cd.c | 1921 ----------- sys/dev/ata/atapi-cd.h | 315 -- sys/dev/ata/atapi-fd.c | 440 --- sys/dev/ata/atapi-fd.h | 86 - sys/dev/ata/atapi-tape.c | 739 ----- sys/dev/ata/atapi-tape.h | 157 - sys/dev/ata/chipsets/ata-acard.c | 100 - sys/dev/ata/chipsets/ata-acerlabs.c | 2 - sys/dev/ata/chipsets/ata-intel.c | 29 - sys/dev/ata/chipsets/ata-ite.c | 2 - sys/dev/ata/chipsets/ata-serverworks.c | 29 - sys/dev/ata/chipsets/ata-siliconimage.c | 2 - 28 files changed, 2 insertions(+), 13814 deletions(-) delete mode 100644 sys/dev/ata/ata-disk.c delete mode 100644 sys/dev/ata/ata-disk.h delete mode 100644 sys/dev/ata/ata-raid-ddf.h delete mode 100644 sys/dev/ata/ata-raid.c delete mode 100644 sys/dev/ata/ata-raid.h delete mode 100644 sys/dev/ata/atapi-cam.c delete mode 100644 sys/dev/ata/atapi-cd.c delete mode 100644 sys/dev/ata/atapi-cd.h delete mode 100644 sys/dev/ata/atapi-fd.c delete mode 100644 sys/dev/ata/atapi-fd.h delete mode 100644 sys/dev/ata/atapi-tape.c delete mode 100644 sys/dev/ata/atapi-tape.h (limited to 'sys/dev/ata') diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 2003ff5..3327a9d 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -51,90 +51,33 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef ATA_CAM #include #include #include #include #include -#endif - -#ifndef ATA_CAM -/* device structure */ -static d_ioctl_t ata_ioctl; -static struct cdevsw ata_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, /* we need this as newbus isn't mpsafe */ - .d_ioctl = ata_ioctl, - .d_name = "ata", -}; -#endif /* prototypes */ -#ifndef ATA_CAM -static void ata_boot_attach(void); -static device_t ata_add_child(device_t, struct ata_device *, int); -#else static void ataaction(struct cam_sim *sim, union ccb *ccb); static void atapoll(struct cam_sim *sim); -#endif static void ata_conn_event(void *, int); -#ifndef ATA_CAM -static void bswap(int8_t *, int); -static void btrim(int8_t *, int); -static void bpack(int8_t *, int8_t *, int); -#endif static void ata_interrupt_locked(void *data); -#ifdef ATA_CAM static void ata_periodic_poll(void *data); -#endif /* global vars */ MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer"); int (*ata_raid_ioctl_func)(u_long cmd, caddr_t data) = NULL; -#ifndef ATA_CAM -struct intr_config_hook *ata_delayed_attach = NULL; -#endif devclass_t ata_devclass; uma_zone_t ata_request_zone; -uma_zone_t ata_composite_zone; -#ifndef ATA_CAM -int ata_wc = 1; -int ata_setmax = 0; -#endif int ata_dma_check_80pin = 1; -/* local vars */ -#ifndef ATA_CAM -static int ata_dma = 1; -static int atapi_dma = 1; -#endif - /* sysctl vars */ static SYSCTL_NODE(_hw, OID_AUTO, ata, CTLFLAG_RD, 0, "ATA driver parameters"); -#ifndef ATA_CAM -TUNABLE_INT("hw.ata.ata_dma", &ata_dma); -SYSCTL_INT(_hw_ata, OID_AUTO, ata_dma, CTLFLAG_RDTUN, &ata_dma, 0, - "ATA disk DMA mode control"); -#endif TUNABLE_INT("hw.ata.ata_dma_check_80pin", &ata_dma_check_80pin); SYSCTL_INT(_hw_ata, OID_AUTO, ata_dma_check_80pin, CTLFLAG_RW, &ata_dma_check_80pin, 1, "Check for 80pin cable before setting ATA DMA mode"); -#ifndef ATA_CAM -TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); -SYSCTL_INT(_hw_ata, OID_AUTO, atapi_dma, CTLFLAG_RDTUN, &atapi_dma, 0, - "ATAPI device DMA mode control"); -TUNABLE_INT("hw.ata.wc", &ata_wc); -SYSCTL_INT(_hw_ata, OID_AUTO, wc, CTLFLAG_RDTUN, &ata_wc, 0, - "ATA disk write caching"); -TUNABLE_INT("hw.ata.setmax", &ata_setmax); -SYSCTL_INT(_hw_ata, OID_AUTO, setmax, CTLFLAG_RDTUN, &ata_setmax, 0, - "ATA disk set max native address"); -#endif -#ifdef ATA_CAM FEATURE(ata_cam, "ATA devices are accessed through the cam(4) driver"); -#endif /* * newbus device interface related functions @@ -150,12 +93,10 @@ ata_attach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); int error, rid; -#ifdef ATA_CAM struct cam_devq *devq; const char *res; char buf[64]; int i, mode; -#endif /* check that we have a virgin channel to attach */ if (ch->r_irq) @@ -166,13 +107,7 @@ ata_attach(device_t dev) ch->state = ATA_IDLE; bzero(&ch->state_mtx, sizeof(struct mtx)); mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF); -#ifndef ATA_CAM - bzero(&ch->queue_mtx, sizeof(struct mtx)); - mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF); - TAILQ_INIT(&ch->ata_queue); -#endif TASK_INIT(&ch->conntask, 0, ata_conn_event, dev); -#ifdef ATA_CAM for (i = 0; i < 16; i++) { ch->user[i].revision = 0; snprintf(buf, sizeof(buf), "dev%d.sata_rev", i); @@ -207,15 +142,6 @@ ata_attach(device_t dev) ch->user[i].caps |= CTS_SATA_CAPS_D_PMREQ; } callout_init(&ch->poll_callout, 1); -#endif - -#ifndef ATA_CAM - /* reset the controller HW, the channel and device(s) */ - while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) - pause("ataatch", 1); - ATA_RESET(dev); - ATA_LOCKING(dev, ATA_LF_UNLOCK); -#endif /* allocate DMA resources if DMA HW present*/ if (ch->dma.alloc) @@ -236,12 +162,6 @@ ata_attach(device_t dev) return error; } -#ifndef ATA_CAM - /* probe and attach devices on this channel unless we are in early boot */ - if (!ata_delayed_attach) - ata_identify(dev); - return (0); -#else if (ch->flags & ATA_PERIODIC_POLL) callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); mtx_lock(&ch->state_mtx); @@ -286,17 +206,12 @@ err1: if (ch->flags & ATA_PERIODIC_POLL) callout_drain(&ch->poll_callout); return (error); -#endif } int ata_detach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); -#ifndef ATA_CAM - device_t *children; - int nchildren, i; -#endif /* check that we have a valid channel to detach */ if (!ch->r_irq) @@ -306,23 +221,11 @@ ata_detach(device_t dev) mtx_lock(&ch->state_mtx); ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); -#ifdef ATA_CAM if (ch->flags & ATA_PERIODIC_POLL) callout_drain(&ch->poll_callout); -#endif - -#ifndef ATA_CAM - /* detach & delete all children */ - if (!device_get_children(dev, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) - if (children[i]) - device_delete_child(dev, children[i]); - free(children, M_TEMP); - } -#endif + taskqueue_drain(taskqueue_thread, &ch->conntask); -#ifdef ATA_CAM mtx_lock(&ch->state_mtx); xpt_async(AC_LOST_DEVICE, ch->path, NULL); xpt_free_path(ch->path); @@ -330,7 +233,6 @@ ata_detach(device_t dev) cam_sim_free(ch->sim, /*free_devq*/TRUE); ch->sim = NULL; mtx_unlock(&ch->state_mtx); -#endif /* release resources */ bus_teardown_intr(dev, ch->r_irq, ch->ih); @@ -342,9 +244,6 @@ ata_detach(device_t dev) ch->dma.free(dev); mtx_destroy(&ch->state_mtx); -#ifndef ATA_CAM - mtx_destroy(&ch->queue_mtx); -#endif return 0; } @@ -352,7 +251,6 @@ static void ata_conn_event(void *context, int dummy) { device_t dev = (device_t)context; -#ifdef ATA_CAM struct ata_channel *ch = device_get_softc(dev); union ccb *ccb; @@ -372,9 +270,6 @@ ata_conn_event(void *context, int dummy) } xpt_rescan(ccb); mtx_unlock(&ch->state_mtx); -#else - ata_reinit(dev); -#endif } int @@ -382,94 +277,7 @@ ata_reinit(device_t dev) { struct ata_channel *ch = device_get_softc(dev); struct ata_request *request; -#ifndef ATA_CAM - device_t *children; - int nchildren, i; - - /* check that we have a valid channel to reinit */ - if (!ch || !ch->r_irq) - return ENXIO; - - if (bootverbose) - device_printf(dev, "reiniting channel ..\n"); - - /* poll for locking the channel */ - while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) - pause("atarini", 1); - - /* catch eventual request in ch->running */ - mtx_lock(&ch->state_mtx); - if (ch->state & ATA_STALL_QUEUE) { - /* Recursive reinits and reinits during detach prohobited. */ - mtx_unlock(&ch->state_mtx); - return (ENXIO); - } - if ((request = ch->running)) - callout_stop(&request->callout); - ch->running = NULL; - - /* unconditionally grap the channel lock */ - ch->state |= ATA_STALL_QUEUE; - mtx_unlock(&ch->state_mtx); - /* reset the controller HW, the channel and device(s) */ - ATA_RESET(dev); - - /* reinit the children and delete any that fails */ - if (!device_get_children(dev, &children, &nchildren)) { - mtx_lock(&Giant); /* newbus suckage it needs Giant */ - for (i = 0; i < nchildren; i++) { - /* did any children go missing ? */ - if (children[i] && device_is_attached(children[i]) && - ATA_REINIT(children[i])) { - /* - * if we had a running request and its device matches - * this child we need to inform the request that the - * device is gone. - */ - if (request && request->dev == children[i]) { - request->result = ENXIO; - device_printf(request->dev, "FAILURE - device detached\n"); - - /* if not timeout finish request here */ - if (!(request->flags & ATA_R_TIMEOUT)) - ata_finish(request); - request = NULL; - } - device_delete_child(dev, children[i]); - } - } - free(children, M_TEMP); - mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ - } - - /* if we still have a good request put it on the queue again */ - if (request && !(request->flags & ATA_R_TIMEOUT)) { - device_printf(request->dev, - "WARNING - %s requeued due to channel reset", - ata_cmd2str(request)); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - request->flags |= ATA_R_REQUEUE; - ata_queue_request(request); - } - - /* we're done release the channel for new work */ - mtx_lock(&ch->state_mtx); - ch->state = ATA_IDLE; - mtx_unlock(&ch->state_mtx); - ATA_LOCKING(dev, ATA_LF_UNLOCK); - - /* Add new children. */ -/* ata_identify(dev); */ - - if (bootverbose) - device_printf(dev, "reinit done ..\n"); - - /* kick off requests on the queue */ - ata_start(dev); -#else xpt_freeze_simq(ch->sim, 1); if ((request = ch->running)) { ch->running = NULL; @@ -486,7 +294,6 @@ ata_reinit(device_t dev) /* Tell the XPT about the event */ xpt_async(AC_BUS_RESET, ch->path, NULL); xpt_release_simq(ch->sim, TRUE); -#endif return(0); } @@ -499,7 +306,6 @@ ata_suspend(device_t dev) if (!dev || !(ch = device_get_softc(dev))) return ENXIO; -#ifdef ATA_CAM if (ch->flags & ATA_PERIODIC_POLL) callout_drain(&ch->poll_callout); mtx_lock(&ch->state_mtx); @@ -507,20 +313,6 @@ ata_suspend(device_t dev) while (ch->state != ATA_IDLE) msleep(ch, &ch->state_mtx, PRIBIO, "atasusp", hz/100); mtx_unlock(&ch->state_mtx); -#else - /* wait for the channel to be IDLE or detached before suspending */ - while (ch->r_irq) { - mtx_lock(&ch->state_mtx); - if (ch->state == ATA_IDLE) { - ch->state = ATA_ACTIVE; - mtx_unlock(&ch->state_mtx); - break; - } - mtx_unlock(&ch->state_mtx); - tsleep(ch, PRIBIO, "atasusp", hz/10); - } - ATA_LOCKING(dev, ATA_LF_UNLOCK); -#endif return(0); } @@ -534,36 +326,25 @@ ata_resume(device_t dev) if (!dev || !(ch = device_get_softc(dev))) return ENXIO; -#ifdef ATA_CAM mtx_lock(&ch->state_mtx); error = ata_reinit(dev); xpt_release_simq(ch->sim, TRUE); mtx_unlock(&ch->state_mtx); if (ch->flags & ATA_PERIODIC_POLL) callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); -#else - /* reinit the devices, we dont know what mode/state they are in */ - error = ata_reinit(dev); - /* kick off requests on the queue */ - ata_start(dev); -#endif return error; } void ata_interrupt(void *data) { -#ifdef ATA_CAM struct ata_channel *ch = (struct ata_channel *)data; mtx_lock(&ch->state_mtx); xpt_batch_start(ch->sim); -#endif ata_interrupt_locked(data); -#ifdef ATA_CAM xpt_batch_done(ch->sim); mtx_unlock(&ch->state_mtx); -#endif } static void @@ -572,9 +353,6 @@ ata_interrupt_locked(void *data) struct ata_channel *ch = (struct ata_channel *)data; struct ata_request *request; -#ifndef ATA_CAM - mtx_lock(&ch->state_mtx); -#endif do { /* ignore interrupt if its not for us */ if (ch->hw.status && !ch->hw.status(ch->dev)) @@ -600,22 +378,12 @@ ata_interrupt_locked(void *data) ch->running = NULL; if (ch->state == ATA_ACTIVE) ch->state = ATA_IDLE; -#ifdef ATA_CAM ata_cam_end_transaction(ch->dev, request); -#else - mtx_unlock(&ch->state_mtx); - ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); - ata_finish(request); -#endif return; } } while (0); -#ifndef ATA_CAM - mtx_unlock(&ch->state_mtx); -#endif } -#ifdef ATA_CAM static void ata_periodic_poll(void *data) { @@ -624,7 +392,6 @@ ata_periodic_poll(void *data) callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); ata_interrupt(ch); } -#endif void ata_print_cable(device_t dev, u_int8_t *who) @@ -633,468 +400,9 @@ ata_print_cable(device_t dev, u_int8_t *who) "DMA limited to UDMA33, %s found non-ATA66 cable\n", who); } -#ifndef ATA_CAM -int -ata_check_80pin(device_t dev, int mode) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (!ata_dma_check_80pin) { - if (bootverbose) - device_printf(dev, "Skipping 80pin cable check\n"); - return mode; - } - - if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) { - ata_print_cable(dev, "device"); - mode = ATA_UDMA2; - } - return mode; -} -#endif - -#ifndef ATA_CAM -void -ata_setmode(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - int error, mode, pmode; - - mode = atadev->mode; - do { - pmode = mode = ata_limit_mode(dev, mode, ATA_DMA_MAX); - mode = ATA_SETMODE(device_get_parent(dev), atadev->unit, mode); - if ((ch->flags & (ATA_CHECKS_CABLE | ATA_SATA)) == 0) - mode = ata_check_80pin(dev, mode); - } while (pmode != mode); /* Interate till successfull negotiation. */ - error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); - if (bootverbose) - device_printf(dev, "%ssetting %s\n", - (error) ? "FAILURE " : "", ata_mode2str(mode)); - atadev->mode = mode; -} -#endif - -/* - * device related interfaces - */ -#ifndef ATA_CAM -static int -ata_ioctl(struct cdev *dev, u_long cmd, caddr_t data, - int32_t flag, struct thread *td) -{ - device_t device, *children; - struct ata_ioc_devices *devices = (struct ata_ioc_devices *)data; - int *value = (int *)data; - int i, nchildren, error = ENOTTY; - - switch (cmd) { - case IOCATAGMAXCHANNEL: - /* In case we have channel 0..n this will return n+1. */ - *value = devclass_get_maxunit(ata_devclass); - error = 0; - break; - - case IOCATAREINIT: - if (*value >= devclass_get_maxunit(ata_devclass) || - !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) - return ENXIO; - error = ata_reinit(device); - break; - - case IOCATAATTACH: - if (*value >= devclass_get_maxunit(ata_devclass) || - !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) - return ENXIO; - error = DEVICE_ATTACH(device); - break; - - case IOCATADETACH: - if (*value >= devclass_get_maxunit(ata_devclass) || - !(device = devclass_get_device(ata_devclass, *value)) || - !device_is_attached(device)) - return ENXIO; - error = DEVICE_DETACH(device); - break; - - case IOCATADEVICES: - if (devices->channel >= devclass_get_maxunit(ata_devclass) || - !(device = devclass_get_device(ata_devclass, devices->channel)) || - !device_is_attached(device)) - 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) { /* XXX SOS PM */ - 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) { /* XXX SOS PM */ - 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_raid_ioctl_func) - error = ata_raid_ioctl_func(cmd, data); - } - return error; -} -#endif - -#ifndef ATA_CAM -int -ata_device_ioctl(device_t dev, u_long cmd, caddr_t data) -{ - struct ata_device *atadev = device_get_softc(dev); - struct ata_channel *ch = device_get_softc(device_get_parent(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 (ioc_request->count > - (ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS)) { - return (EFBIG); - } - if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) { - return ENOMEM; - } - if (!(request = ata_alloc_request())) { - free(buf, M_ATA); - return ENOMEM; - } - request->dev = atadev->dev; - 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; - } - } - 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) { - bcopy(&request->u.atapi.sense, &ioc_request->u.atapi.sense, - sizeof(struct atapi_sense)); - } - else { - 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: - ata_getparam(atadev, 0); - bcopy(&atadev->param, params, sizeof(struct ata_params)); - return 0; - - case IOCATASMODE: - atadev->mode = *mode; - ata_setmode(dev); - return 0; - - case IOCATAGMODE: - *mode = atadev->mode | - (ATA_GETREV(device_get_parent(dev), atadev->unit) << 8); - return 0; - case IOCATASSPINDOWN: - atadev->spindown = *mode; - return 0; - case IOCATAGSPINDOWN: - *mode = atadev->spindown; - return 0; - default: - return ENOTTY; - } -} -#endif - -#ifndef ATA_CAM -static void -ata_boot_attach(void) -{ - struct ata_channel *ch; - int ctlr; - - mtx_lock(&Giant); /* newbus suckage it needs Giant */ - - /* kick off probe and attach on all channels */ - for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) { - if ((ch = devclass_get_softc(ata_devclass, ctlr))) { - ata_identify(ch->dev); - } - } - - /* release the hook that got us here, we are only needed once during boot */ - if (ata_delayed_attach) { - config_intrhook_disestablish(ata_delayed_attach); - free(ata_delayed_attach, M_TEMP); - ata_delayed_attach = NULL; - } - - mtx_unlock(&Giant); /* newbus suckage dealt with, release Giant */ -} -#endif - /* * misc support functions */ -#ifndef ATA_CAM -static device_t -ata_add_child(device_t parent, struct ata_device *atadev, int unit) -{ - device_t child; - - if ((child = device_add_child(parent, (unit < 0) ? NULL : "ad", unit))) { - device_set_softc(child, atadev); - device_quiet(child); - atadev->dev = child; - atadev->max_iosize = DEV_BSIZE; - atadev->mode = ATA_PIO_MAX; - } - return child; -} -#endif - -#ifndef ATA_CAM -int -ata_getparam(struct ata_device *atadev, int init) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(atadev->dev)); - struct ata_request *request; - const char *res; - char buf[64]; - u_int8_t command = 0; - int error = ENOMEM, retries = 2, mode = -1; - - if (ch->devices & (ATA_ATA_MASTER << atadev->unit)) - command = ATA_ATA_IDENTIFY; - if (ch->devices & (ATA_ATAPI_MASTER << atadev->unit)) - command = ATA_ATAPI_IDENTIFY; - if (!command) - return ENXIO; - - while (retries-- > 0 && error) { - if (!(request = ata_alloc_request())) - break; - request->dev = atadev->dev; - request->timeout = 1; - request->retries = 0; - request->u.ata.command = command; - request->flags = (ATA_R_READ|ATA_R_AT_HEAD|ATA_R_DIRECT); - if (!bootverbose) - request->flags |= ATA_R_QUIET; - request->data = (void *)&atadev->param; - request->bytecount = sizeof(struct ata_params); - request->donecount = 0; - request->transfersize = DEV_BSIZE; - ata_queue_request(request); - error = request->result; - ata_free_request(request); - } - - if (!error && (isprint(atadev->param.model[0]) || - isprint(atadev->param.model[1]))) { - struct ata_params *atacap = &atadev->param; - int16_t *ptr; - - for (ptr = (int16_t *)atacap; - ptr < (int16_t *)atacap + sizeof(struct ata_params)/2; ptr++) { - *ptr = le16toh(*ptr); - } - if (!(!strncmp(atacap->model, "FX", 2) || - !strncmp(atacap->model, "NEC", 3) || - !strncmp(atacap->model, "Pioneer", 7) || - !strncmp(atacap->model, "SHARP", 5))) { - bswap(atacap->model, sizeof(atacap->model)); - bswap(atacap->revision, sizeof(atacap->revision)); - bswap(atacap->serial, sizeof(atacap->serial)); - } - btrim(atacap->model, sizeof(atacap->model)); - bpack(atacap->model, atacap->model, sizeof(atacap->model)); - btrim(atacap->revision, sizeof(atacap->revision)); - bpack(atacap->revision, atacap->revision, sizeof(atacap->revision)); - btrim(atacap->serial, sizeof(atacap->serial)); - bpack(atacap->serial, atacap->serial, sizeof(atacap->serial)); - - if (bootverbose) - printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n", - device_get_unit(ch->dev), - ata_unit2str(atadev), - ata_mode2str(ata_pmode(atacap)), - ata_mode2str(ata_wmode(atacap)), - ata_mode2str(ata_umode(atacap)), - (atacap->hwres & ATA_CABLE_ID) ? "80":"40"); - - if (init) { - char buffer[64]; - - sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision); - device_set_desc_copy(atadev->dev, buffer); - if ((atadev->param.config & ATA_PROTO_ATAPI) && - (atadev->param.config != ATA_CFA_MAGIC1) && - (atadev->param.config != ATA_CFA_MAGIC2)) { - if (atapi_dma && - (atadev->param.config & ATA_DRQ_MASK) != ATA_DRQ_INTR && - ata_umode(&atadev->param) >= ATA_UDMA2) - atadev->mode = ATA_DMA_MAX; - } - else { - if (ata_dma && - (ata_umode(&atadev->param) > 0 || - ata_wmode(&atadev->param) > 0)) - atadev->mode = ATA_DMA_MAX; - } - snprintf(buf, sizeof(buf), "dev%d.mode", atadev->unit); - if (resource_string_value(device_get_name(ch->dev), - device_get_unit(ch->dev), buf, &res) == 0) - mode = ata_str2mode(res); - else if (resource_string_value(device_get_name(ch->dev), - device_get_unit(ch->dev), "mode", &res) == 0) - mode = ata_str2mode(res); - if (mode >= 0) - atadev->mode = mode; - } - } - else { - if (!error) - error = ENXIO; - } - return error; -} -#endif - -#ifndef ATA_CAM -int -ata_identify(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - struct ata_device *atadev; - device_t *children; - device_t child, master = NULL; - int nchildren, i, n = ch->devices; - - if (bootverbose) - device_printf(dev, "Identifying devices: %08x\n", ch->devices); - - mtx_lock(&Giant); - /* Skip existing devices. */ - if (!device_get_children(dev, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) { - if (children[i] && (atadev = device_get_softc(children[i]))) - n &= ~((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << atadev->unit); - } - free(children, M_TEMP); - } - /* Create new devices. */ - if (bootverbose) - device_printf(dev, "New devices: %08x\n", n); - if (n == 0) { - mtx_unlock(&Giant); - return (0); - } - for (i = 0; i < ATA_PM; ++i) { - if (n & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) { - int unit = -1; - - if (!(atadev = malloc(sizeof(struct ata_device), - M_ATA, M_NOWAIT | M_ZERO))) { - device_printf(dev, "out of memory\n"); - return ENOMEM; - } - atadev->unit = i; -#ifdef ATA_STATIC_ID - if (n & (ATA_ATA_MASTER << i)) - unit = (device_get_unit(dev) << 1) + i; -#endif - if ((child = ata_add_child(dev, atadev, unit))) { - /* - * PATA slave should be identified first, to allow - * device cable detection on master to work properly. - */ - if (i == 0 && (n & ATA_PORTMULTIPLIER) == 0 && - (n & ((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << 1)) != 0) { - master = child; - continue; - } - if (ata_getparam(atadev, 1)) { - device_delete_child(dev, child); - free(atadev, M_ATA); - } - } - else - free(atadev, M_ATA); - } - } - if (master) { - atadev = device_get_softc(master); - if (ata_getparam(atadev, 1)) { - device_delete_child(dev, master); - free(atadev, M_ATA); - } - } - bus_generic_probe(dev); - bus_generic_attach(dev); - mtx_unlock(&Giant); - return 0; -} -#endif - void ata_default_registers(device_t dev) { @@ -1111,110 +419,6 @@ ata_default_registers(device_t dev) ch->r_io[ATA_ALTSTAT].offset = ch->r_io[ATA_CONTROL].offset; } -#ifndef ATA_CAM -void -ata_modify_if_48bit(struct ata_request *request) -{ - struct ata_channel *ch = device_get_softc(request->parent); - struct ata_device *atadev = device_get_softc(request->dev); - - request->flags &= ~ATA_R_48BIT; - - if (((request->u.ata.lba + request->u.ata.count) >= ATA_MAX_28BIT_LBA || - request->u.ata.count > 256) && - atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { - - /* translate command into 48bit version */ - switch (request->u.ata.command) { - case ATA_READ: - request->u.ata.command = ATA_READ48; - break; - case ATA_READ_MUL: - request->u.ata.command = ATA_READ_MUL48; - break; - case ATA_READ_DMA: - if (ch->flags & ATA_NO_48BIT_DMA) { - if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_READ_MUL48; - else - request->u.ata.command = ATA_READ48; - request->flags &= ~ATA_R_DMA; - } - else - request->u.ata.command = ATA_READ_DMA48; - break; - case ATA_READ_DMA_QUEUED: - if (ch->flags & ATA_NO_48BIT_DMA) { - if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_READ_MUL48; - else - request->u.ata.command = ATA_READ48; - request->flags &= ~ATA_R_DMA; - } - else - request->u.ata.command = ATA_READ_DMA_QUEUED48; - break; - case ATA_WRITE: - request->u.ata.command = ATA_WRITE48; - break; - case ATA_WRITE_MUL: - request->u.ata.command = ATA_WRITE_MUL48; - break; - case ATA_WRITE_DMA: - if (ch->flags & ATA_NO_48BIT_DMA) { - if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_WRITE_MUL48; - else - request->u.ata.command = ATA_WRITE48; - request->flags &= ~ATA_R_DMA; - } - else - request->u.ata.command = ATA_WRITE_DMA48; - break; - case ATA_WRITE_DMA_QUEUED: - if (ch->flags & ATA_NO_48BIT_DMA) { - if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_WRITE_MUL48; - else - request->u.ata.command = ATA_WRITE48; - request->u.ata.command = ATA_WRITE48; - request->flags &= ~ATA_R_DMA; - } - else - request->u.ata.command = ATA_WRITE_DMA_QUEUED48; - break; - case ATA_FLUSHCACHE: - request->u.ata.command = ATA_FLUSHCACHE48; - break; - case ATA_SET_MAX_ADDRESS: - request->u.ata.command = ATA_SET_MAX_ADDRESS48; - break; - default: - return; - } - request->flags |= ATA_R_48BIT; - } - else if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) { - - /* translate command into 48bit version */ - switch (request->u.ata.command) { - case ATA_FLUSHCACHE: - request->u.ata.command = ATA_FLUSHCACHE48; - break; - case ATA_READ_NATIVE_MAX_ADDRESS: - request->u.ata.command = ATA_READ_NATIVE_MAX_ADDRESS48; - break; - case ATA_SET_MAX_ADDRESS: - request->u.ata.command = ATA_SET_MAX_ADDRESS48; - break; - default: - return; - } - request->flags |= ATA_R_48BIT; - } -} -#endif - void ata_udelay(int interval) { @@ -1225,21 +429,6 @@ ata_udelay(int interval) pause("ataslp", interval/(1000000/hz)); } -#ifndef ATA_CAM -const char * -ata_unit2str(struct ata_device *atadev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(atadev->dev)); - static char str[8]; - - if (ch->devices & ATA_PORTMULTIPLIER) - sprintf(str, "port%d", atadev->unit); - else - sprintf(str, "%s", atadev->unit == ATA_MASTER ? "master" : "slave"); - return str; -} -#endif - const char * ata_mode2str(int mode) { @@ -1299,21 +488,6 @@ ata_str2mode(const char *str) return (-1); } -#ifndef ATA_CAM -const char * -ata_satarev2str(int rev) -{ - switch (rev) { - case 0: return ""; - case 1: return "SATA 1.5Gb/s"; - case 2: return "SATA 3Gb/s"; - case 3: return "SATA 6Gb/s"; - case 0xff: return "SATA"; - default: return "???"; - } -} -#endif - int ata_atapi(device_t dev, int target) { @@ -1322,143 +496,6 @@ ata_atapi(device_t dev, int target) return (ch->devices & (ATA_ATAPI_MASTER << target)); } -#ifndef ATA_CAM -int -ata_pmode(struct ata_params *ap) -{ - if (ap->atavalid & ATA_FLAG_64_70) { - if (ap->apiomodes & 0x02) - return ATA_PIO4; - if (ap->apiomodes & 0x01) - return ATA_PIO3; - } - if (ap->mwdmamodes & 0x04) - return ATA_PIO4; - if (ap->mwdmamodes & 0x02) - return ATA_PIO3; - if (ap->mwdmamodes & 0x01) - return ATA_PIO2; - if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200) - return ATA_PIO2; - if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100) - return ATA_PIO1; - if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000) - return ATA_PIO0; - return ATA_PIO0; -} -#endif - -#ifndef ATA_CAM -int -ata_wmode(struct ata_params *ap) -{ - if (ap->mwdmamodes & 0x04) - return ATA_WDMA2; - if (ap->mwdmamodes & 0x02) - return ATA_WDMA1; - if (ap->mwdmamodes & 0x01) - return ATA_WDMA0; - return -1; -} -#endif - -#ifndef ATA_CAM -int -ata_umode(struct ata_params *ap) -{ - if (ap->atavalid & ATA_FLAG_88) { - if (ap->udmamodes & 0x40) - return ATA_UDMA6; - if (ap->udmamodes & 0x20) - return ATA_UDMA5; - if (ap->udmamodes & 0x10) - return ATA_UDMA4; - if (ap->udmamodes & 0x08) - return ATA_UDMA3; - if (ap->udmamodes & 0x04) - return ATA_UDMA2; - if (ap->udmamodes & 0x02) - return ATA_UDMA1; - if (ap->udmamodes & 0x01) - return ATA_UDMA0; - } - return -1; -} -#endif - -#ifndef ATA_CAM -int -ata_limit_mode(device_t dev, int mode, int maxmode) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (maxmode && mode > maxmode) - mode = maxmode; - - if (mode >= ATA_UDMA0 && ata_umode(&atadev->param) > 0) - return min(mode, ata_umode(&atadev->param)); - - if (mode >= ATA_WDMA0 && ata_wmode(&atadev->param) > 0) - return min(mode, ata_wmode(&atadev->param)); - - if (mode > ata_pmode(&atadev->param)) - return min(mode, ata_pmode(&atadev->param)); - - return mode; -} -#endif - -#ifndef ATA_CAM -static void -bswap(int8_t *buf, int len) -{ - u_int16_t *ptr = (u_int16_t*)(buf + len); - - while (--ptr >= (u_int16_t*)buf) - *ptr = ntohs(*ptr); -} -#endif - -#ifndef ATA_CAM -static void -btrim(int8_t *buf, int len) -{ - int8_t *ptr; - - for (ptr = buf; ptr < buf+len; ++ptr) - if (!*ptr || *ptr == '_') - *ptr = ' '; - for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr) - *ptr = 0; -} -#endif - -#ifndef ATA_CAM -static void -bpack(int8_t *src, int8_t *dst, int len) -{ - int i, j, blank; - - for (i = j = blank = 0 ; i < len; i++) { - if (blank && src[i] == ' ') continue; - if (blank && src[i] != ' ') { - dst[j++] = src[i]; - blank = 0; - continue; - } - if (src[i] == ' ') { - blank = 1; - if (i == 0) - continue; - } - dst[j++] = src[i]; - } - if (j < len) - dst[j] = 0x00; -} -#endif - -#ifdef ATA_CAM static void ata_cam_begin_transaction(device_t dev, union ccb *ccb) { @@ -1928,7 +965,6 @@ atapoll(struct cam_sim *sim) ata_interrupt_locked(ch); } -#endif /* * module handeling @@ -1936,38 +972,12 @@ atapoll(struct cam_sim *sim) static int ata_module_event_handler(module_t mod, int what, void *arg) { -#ifndef ATA_CAM - static struct cdev *atacdev; -#endif switch (what) { case MOD_LOAD: -#ifndef ATA_CAM - /* register controlling device */ - atacdev = make_dev(&ata_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "ata"); - - if (cold) { - /* register boot attach to be run when interrupts are enabled */ - if (!(ata_delayed_attach = (struct intr_config_hook *) - malloc(sizeof(struct intr_config_hook), - M_TEMP, M_NOWAIT | M_ZERO))) { - printf("ata: malloc of delayed attach hook failed\n"); - return EIO; - } - ata_delayed_attach->ich_func = (void*)ata_boot_attach; - if (config_intrhook_establish(ata_delayed_attach) != 0) { - printf("ata: config_intrhook_establish failed\n"); - free(ata_delayed_attach, M_TEMP); - } - } -#endif return 0; case MOD_UNLOAD: -#ifndef ATA_CAM - /* deregister controlling device */ - destroy_dev(atacdev); -#endif return 0; default: @@ -1978,25 +988,19 @@ ata_module_event_handler(module_t mod, int what, void *arg) static moduledata_t ata_moduledata = { "ata", ata_module_event_handler, NULL }; DECLARE_MODULE(ata, ata_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND); MODULE_VERSION(ata, 1); -#ifdef ATA_CAM MODULE_DEPEND(ata, cam, 1, 1, 1); -#endif static void ata_init(void) { ata_request_zone = uma_zcreate("ata_request", sizeof(struct ata_request), NULL, NULL, NULL, NULL, 0, 0); - ata_composite_zone = uma_zcreate("ata_composite", - sizeof(struct ata_composite), - NULL, NULL, NULL, NULL, 0, 0); } SYSINIT(ata_register, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL); static void ata_uninit(void) { - uma_zdestroy(ata_composite_zone); uma_zdestroy(ata_request_zone); } SYSUNINIT(ata_unregister, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_uninit, NULL); diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index cdd4429..01b3eac 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -423,9 +423,7 @@ struct ata_request { struct ata_composite *composite; /* for composite atomic ops */ void *driver; /* driver specific */ TAILQ_ENTRY(ata_request) chain; /* list management */ -#ifdef ATA_CAM union ccb *ccb; -#endif }; /* define this for debugging request processing */ @@ -532,7 +530,6 @@ struct ata_resource { int offset; }; -#ifdef ATA_CAM struct ata_cam_device { u_int revision; int mode; @@ -540,7 +537,6 @@ struct ata_cam_device { u_int atapi; u_int caps; }; -#endif /* structure describing an ATA channel */ struct ata_channel { @@ -580,20 +576,13 @@ struct ata_channel { #define ATA_ACTIVE 0x0001 #define ATA_STALL_QUEUE 0x0002 -#ifndef ATA_CAM - struct mtx queue_mtx; /* queue lock */ - TAILQ_HEAD(, ata_request) ata_queue; /* head of ATA queue */ - struct ata_request *freezepoint; /* composite freezepoint */ -#endif struct ata_request *running; /* currently running request */ struct task conntask; /* PHY events handling task */ -#ifdef ATA_CAM struct cam_sim *sim; struct cam_path *path; struct ata_cam_device user[16]; /* User-specified settings */ struct ata_cam_device curr[16]; /* Current settings */ int requestsense; /* CCB waiting for SENSE. */ -#endif struct callout poll_callout; /* Periodic status poll. */ }; @@ -632,17 +621,7 @@ void ata_print_cable(device_t dev, u_int8_t *who); int ata_str2mode(const char *str); const char *ata_satarev2str(int rev); int ata_atapi(device_t dev, int target); -#ifndef ATA_CAM -int ata_identify(device_t dev); -void ata_modify_if_48bit(struct ata_request *request); -int ata_pmode(struct ata_params *ap); -int ata_wmode(struct ata_params *ap); -int ata_umode(struct ata_params *ap); -int ata_limit_mode(device_t dev, int mode, int maxmode); -int ata_check_80pin(device_t dev, int mode); -#else void ata_cam_end_transaction(device_t dev, struct ata_request *request); -#endif /* ata-queue.c: */ int ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count); @@ -685,11 +664,6 @@ extern uma_zone_t ata_request_zone; uma_zfree(ata_request_zone, request); \ } -/* macros for alloc/free of struct ata_composite */ -extern uma_zone_t ata_composite_zone; -#define ata_alloc_composite() uma_zalloc(ata_composite_zone, M_NOWAIT | M_ZERO) -#define ata_free_composite(composite) uma_zfree(ata_composite_zone, composite) - MALLOC_DECLARE(M_ATA); /* misc newbus defines */ diff --git a/sys/dev/ata/ata-cbus.c b/sys/dev/ata/ata-cbus.c index db7f2d1..94376be 100644 --- a/sys/dev/ata/ata-cbus.c +++ b/sys/dev/ata/ata-cbus.c @@ -53,12 +53,6 @@ struct ata_cbus_controller { struct resource *bankio; struct resource *irq; void *ih; -#ifndef ATA_CAM - struct mtx bank_mtx; - int locked_bank; - int restart_bank; - int hardware_bank; -#endif int channels; struct { void (*function)(void *); @@ -68,9 +62,6 @@ struct ata_cbus_controller { /* local prototypes */ static void ata_cbus_intr(void *); -#ifndef ATA_CAM -static int ata_cbuschannel_banking(device_t dev, int flags); -#endif static int ata_cbus_probe(device_t dev) @@ -160,17 +151,9 @@ ata_cbus_attach(device_t dev) return ENXIO; } -#ifndef ATA_CAM - ctlr->channels = 2; - mtx_init(&ctlr->bank_mtx, "ATA cbus bank lock", NULL, MTX_DEF); - ctlr->hardware_bank = -1; - ctlr->locked_bank = -1; - ctlr->restart_bank = -1; -#else /* Work around the lack of channel serialization in ATA_CAM. */ ctlr->channels = 1; device_printf(dev, "second channel ignored\n"); -#endif for (unit = 0; unit < ctlr->channels; unit++) { child = device_add_child(dev, "ata", unit); @@ -244,10 +227,7 @@ ata_cbus_intr(void *data) for (unit = 0; unit < ctlr->channels; unit++) { if (!(ch = ctlr->interrupt[unit].argument)) continue; -#ifndef ATA_CAM - if (ata_cbuschannel_banking(ch->dev, ATA_LF_WHICH) == unit) -#endif - ctlr->interrupt[unit].function(ch); + ctlr->interrupt[unit].function(ch); } } @@ -349,50 +329,6 @@ ata_cbuschannel_resume(device_t dev) return ata_resume(dev); } -#ifndef ATA_CAM -static int -ata_cbuschannel_banking(device_t dev, int flags) -{ - struct ata_cbus_controller *ctlr = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); - int res; - - mtx_lock(&ctlr->bank_mtx); - switch (flags) { - case ATA_LF_LOCK: - if (ctlr->locked_bank == -1) - ctlr->locked_bank = ch->unit; - if (ctlr->locked_bank == ch->unit) { - ctlr->hardware_bank = ch->unit; - ATA_OUTB(ctlr->bankio, 0, ch->unit); - } - else - ctlr->restart_bank = ch->unit; - break; - - case ATA_LF_UNLOCK: - if (ctlr->locked_bank == ch->unit) { - ctlr->locked_bank = -1; - if (ctlr->restart_bank != -1) { - if ((ch = ctlr->interrupt[ctlr->restart_bank].argument)) { - ctlr->restart_bank = -1; - mtx_unlock(&ctlr->bank_mtx); - ata_start(ch->dev); - return -1; - } - } - } - break; - - case ATA_LF_WHICH: - break; - } - res = ctlr->locked_bank; - mtx_unlock(&ctlr->bank_mtx); - return res; -} -#endif - static device_method_t ata_cbuschannel_methods[] = { /* device interface */ DEVMETHOD(device_probe, ata_cbuschannel_probe), @@ -400,11 +336,6 @@ static device_method_t ata_cbuschannel_methods[] = { DEVMETHOD(device_detach, ata_cbuschannel_detach), DEVMETHOD(device_suspend, ata_cbuschannel_suspend), DEVMETHOD(device_resume, ata_cbuschannel_resume), - -#ifndef ATA_CAM - /* ATA methods */ - DEVMETHOD(ata_locking, ata_cbuschannel_banking), -#endif DEVMETHOD_END }; diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c deleted file mode 100644 index 22e9661..0000000 --- a/sys/dev/ata/ata-disk.c +++ /dev/null @@ -1,607 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ata.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* prototypes */ -static void ad_init(device_t dev); -static int ad_get_geometry(device_t dev); -static void ad_set_geometry(device_t dev); -static void ad_done(struct ata_request *request); -static void ad_describe(device_t dev); -static int ad_version(u_int16_t version); -static disk_strategy_t ad_strategy; -static disk_ioctl_t ad_ioctl; -static dumper_t ad_dump; - -/* - * Most platforms map firmware geom to actual, but some don't. If - * not overridden, default to nothing. - */ -#ifndef ata_disk_firmware_geom_adjust -#define ata_disk_firmware_geom_adjust(disk) -#endif - -/* local vars */ -static MALLOC_DEFINE(M_AD, "ad_driver", "ATA disk driver"); - -static int -ad_probe(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (!(atadev->param.config & ATA_PROTO_ATAPI) || - (atadev->param.config == ATA_CFA_MAGIC1) || - (atadev->param.config == ATA_CFA_MAGIC2) || - (atadev->param.config == ATA_CFA_MAGIC3)) - return 0; - else - return ENXIO; -} - -static int -ad_attach(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct ad_softc *adp; - device_t parent; - - /* check that we have a virgin disk to attach */ - if (device_get_ivars(dev)) - return EEXIST; - - if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) { - device_printf(dev, "out of memory\n"); - return ENOMEM; - } - device_set_ivars(dev, adp); - - /* get device geometry into internal structs */ - if (ad_get_geometry(dev)) - return ENXIO; - - /* set the max size if configured */ - if (ata_setmax) - ad_set_geometry(dev); - - /* init device parameters */ - ad_init(dev); - - /* announce we are here */ - ad_describe(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; - adp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; - if (atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) - adp->disk->d_maxsize = min(adp->disk->d_maxsize, 65536 * DEV_BSIZE); - else /* 28bit ATA command limit */ - adp->disk->d_maxsize = min(adp->disk->d_maxsize, 256 * DEV_BSIZE); - adp->disk->d_sectorsize = DEV_BSIZE; - adp->disk->d_mediasize = DEV_BSIZE * (off_t)adp->total_secs; - adp->disk->d_fwsectors = adp->sectors; - adp->disk->d_fwheads = adp->heads; - adp->disk->d_unit = device_get_unit(dev); - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - adp->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; - if ((atadev->param.support.command2 & ATA_SUPPORT_CFA) || - atadev->param.config == ATA_PROTO_CFA) - adp->disk->d_flags |= DISKFLAG_CANDELETE; - strlcpy(adp->disk->d_ident, atadev->param.serial, - sizeof(adp->disk->d_ident)); - strlcpy(adp->disk->d_descr, atadev->param.model, - sizeof(adp->disk->d_descr)); - parent = device_get_parent(ch->dev); - if (parent != NULL && device_get_parent(parent) != NULL && - (device_get_devclass(parent) == - devclass_find("atapci") || - device_get_devclass(device_get_parent(parent)) == - devclass_find("pci"))) { - adp->disk->d_hba_vendor = pci_get_vendor(parent); - adp->disk->d_hba_device = pci_get_device(parent); - adp->disk->d_hba_subvendor = pci_get_subvendor(parent); - adp->disk->d_hba_subdevice = pci_get_subdevice(parent); - } - ata_disk_firmware_geom_adjust(adp->disk); - disk_create(adp->disk, DISK_VERSION); - device_add_child(dev, "subdisk", device_get_unit(dev)); - bus_generic_attach(dev); - - callout_init(&atadev->spindown_timer, 1); - return 0; -} - -static int -ad_detach(device_t dev) -{ - struct ad_softc *adp = device_get_ivars(dev); - struct ata_device *atadev = device_get_softc(dev); - - /* check that we have a valid disk to detach */ - if (!device_get_ivars(dev)) - return ENXIO; - - /* destroy the power timeout */ - callout_drain(&atadev->spindown_timer); - - /* detach & delete all children */ - device_delete_children(dev); - - /* destroy disk from the system so we don't get any further requests */ - disk_destroy(adp->disk); - - /* fail requests on the queue and any that's "in flight" for this device */ - ata_fail_requests(dev); - - /* don't leave anything behind */ - device_set_ivars(dev, NULL); - free(adp, M_AD); - return 0; -} - -static int -ad_shutdown(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); - return 0; -} - -static int -ad_reinit(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - - /* if detach pending, return error */ - if (!(ch->devices & (ATA_ATA_MASTER << atadev->unit))) - return 1; - - ad_init(dev); - return 0; -} - -static void -ad_power_callback(struct ata_request *request) -{ - device_printf(request->dev, "drive spun down.\n"); - ata_free_request(request); -} - -static void -ad_spindown(void *priv) -{ - device_t dev = priv; - struct ata_device *atadev = device_get_softc(dev); - struct ata_request *request; - - if (!atadev->spindown) - return; - device_printf(dev, "Idle, spin down\n"); - atadev->spindown_state = 1; - if (!(request = ata_alloc_request())) { - device_printf(dev, "FAILURE - out of memory in ad_spindown\n"); - return; - } - request->dev = dev; - request->flags = ATA_R_CONTROL; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 1; - request->callback = ad_power_callback; - request->u.ata.command = ATA_STANDBY_IMMEDIATE; - ata_queue_request(request); -} - - -static void -ad_strategy(struct bio *bp) -{ - device_t dev = bp->bio_disk->d_drv1; - struct ata_device *atadev = device_get_softc(dev); - struct ata_request *request; - - if (atadev->spindown) - callout_reset(&atadev->spindown_timer, hz * atadev->spindown, - ad_spindown, dev); - - if (!(request = ata_alloc_request())) { - device_printf(dev, "FAILURE - out of memory in start\n"); - biofinish(bp, NULL, ENOMEM); - return; - } - - /* setup request */ - request->dev = dev; - request->bio = bp; - request->callback = ad_done; - if (atadev->spindown_state) { - device_printf(dev, "request while spun down, starting.\n"); - atadev->spindown_state = 0; - request->timeout = MAX(ATA_REQUEST_TIMEOUT, 31); - } - else { - request->timeout = ATA_REQUEST_TIMEOUT; - } - request->retries = 2; - request->data = bp->bio_data; - request->bytecount = bp->bio_bcount; - request->u.ata.lba = bp->bio_pblkno; - request->u.ata.count = request->bytecount / DEV_BSIZE; - request->transfersize = min(bp->bio_bcount, atadev->max_iosize); - - switch (bp->bio_cmd) { - case BIO_READ: - request->flags = ATA_R_READ; - if (atadev->mode >= ATA_DMA) { - request->u.ata.command = ATA_READ_DMA; - request->flags |= ATA_R_DMA; - } - else if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_READ_MUL; - else - request->u.ata.command = ATA_READ; - break; - case BIO_WRITE: - request->flags = ATA_R_WRITE; - if (atadev->mode >= ATA_DMA) { - request->u.ata.command = ATA_WRITE_DMA; - request->flags |= ATA_R_DMA; - } - else if (request->transfersize > DEV_BSIZE) - request->u.ata.command = ATA_WRITE_MUL; - else - request->u.ata.command = ATA_WRITE; - break; - case BIO_DELETE: - request->flags = ATA_R_CONTROL; - request->u.ata.command = ATA_CFA_ERASE; - request->transfersize = 0; - request->donecount = bp->bio_bcount; - break; - case BIO_FLUSH: - request->u.ata.lba = 0; - request->u.ata.count = 0; - request->u.ata.feature = 0; - request->bytecount = 0; - request->transfersize = 0; - request->flags = ATA_R_CONTROL; - request->u.ata.command = ATA_FLUSHCACHE; - break; - default: - device_printf(dev, "FAILURE - unknown BIO operation\n"); - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - request->flags |= ATA_R_ORDERED; - ata_queue_request(request); -} - -static void -ad_done(struct ata_request *request) -{ - struct bio *bp = request->bio; - - /* finish up transfer */ - if ((bp->bio_error = request->result)) - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount - request->donecount; - biodone(bp); - 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) -{ - struct disk *dp = arg; - device_t dev = dp->d_drv1; - struct bio bp; - - /* XXX: Drop pre-dump request queue. Long request queue processing - * causes stack overflow in ATA working in dumping (interruptless) mode. - * Conter-XXX: To make dump coherent we should avoid doing anything - * else while dumping. - */ - ata_drop_requests(dev); - - /* length zero is special and really means flush buffers to media */ - if (!length) { - struct ata_device *atadev = device_get_softc(dev); - int error = 0; - - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - error = ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); - return error; - } - - bzero(&bp, sizeof(struct bio)); - bp.bio_disk = dp; - bp.bio_pblkno = offset / DEV_BSIZE; - bp.bio_bcount = length; - bp.bio_data = virtual; - bp.bio_cmd = BIO_WRITE; - ad_strategy(&bp); - return bp.bio_error; -} - -static void -ad_init(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - ata_setmode(dev); - - /* enable readahead caching */ - if (atadev->param.support.command1 & ATA_SUPPORT_LOOKAHEAD) - ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_ENAB_RCACHE, 0, 0); - - /* enable write caching if supported and configured */ - if (atadev->param.support.command1 & ATA_SUPPORT_WRITECACHE) { - if (ata_wc) - ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_ENAB_WCACHE, 0, 0); - else - ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_DIS_WCACHE, 0, 0); - } - - /* use multiple sectors/interrupt if device supports it */ - if (ad_version(atadev->param.version_major)) { - int secsperint = max(1, min(atadev->param.sectors_intr & 0xff, 16)); - - if (!ata_controlcmd(dev, ATA_SET_MULTI, 0, 0, secsperint)) - atadev->max_iosize = secsperint * DEV_BSIZE; - else - atadev->max_iosize = DEV_BSIZE; - } - else - atadev->max_iosize = DEV_BSIZE; -} - -static int -ad_get_geometry(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - struct ad_softc *adp = device_get_ivars(dev); - u_int64_t lbasize48; - u_int32_t lbasize; - - if ((atadev->param.atavalid & ATA_FLAG_54_58) && - atadev->param.current_heads && atadev->param.current_sectors) { - adp->heads = atadev->param.current_heads; - adp->sectors = atadev->param.current_sectors; - adp->total_secs = (u_int32_t)atadev->param.current_size_1 | - ((u_int32_t)atadev->param.current_size_2 << 16); - } - else { - adp->heads = atadev->param.heads; - adp->sectors = atadev->param.sectors; - adp->total_secs = atadev->param.cylinders * adp->heads * adp->sectors; - } - lbasize = (u_int32_t)atadev->param.lba_size_1 | - ((u_int32_t)atadev->param.lba_size_2 << 16); - /* This device exists, but has no size. Filter out this bogus device. */ - if (!lbasize && !adp->total_secs) - return ENXIO; - - /* does this device need oldstyle CHS addressing */ - if (!ad_version(atadev->param.version_major) || !lbasize) - atadev->flags |= ATA_D_USE_CHS; - - /* use the 28bit LBA size if valid or bigger than the CHS mapping */ - if (atadev->param.cylinders == 16383 || adp->total_secs < lbasize) - adp->total_secs = lbasize; - - /* use the 48bit LBA size if valid */ - lbasize48 = ((u_int64_t)atadev->param.lba_size48_1) | - ((u_int64_t)atadev->param.lba_size48_2 << 16) | - ((u_int64_t)atadev->param.lba_size48_3 << 32) | - ((u_int64_t)atadev->param.lba_size48_4 << 48); - if ((atadev->param.support.command2 & ATA_SUPPORT_ADDRESS48) && - lbasize48 > ATA_MAX_28BIT_LBA) - adp->total_secs = lbasize48; - return 0; -} - -static void -ad_set_geometry(device_t dev) -{ - struct ad_softc *adp = device_get_ivars(dev); - struct ata_request *request; - - if (1 | bootverbose) - device_printf(dev, "ORG %ju sectors [%juC/%dH/%dS]\n", adp->total_secs, - adp->total_secs / (adp->heads * adp->sectors), - adp->heads, adp->sectors); - - if (!(request = ata_alloc_request())) - return; - - /* get the max native size the device supports */ - request->dev = dev; - request->u.ata.command = ATA_READ_NATIVE_MAX_ADDRESS; - request->u.ata.lba = 0; - request->u.ata.count = 0; - request->u.ata.feature = 0; - request->flags = ATA_R_CONTROL | ATA_R_QUIET; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 0; - ata_queue_request(request); - if (request->status & ATA_S_ERROR) - goto out; - - if (1 | bootverbose) - device_printf(dev, "MAX %ju sectors\n", request->u.ata.lba + 1); - - /* if original size equals max size nothing more todo */ - if (adp->total_secs >= request->u.ata.lba) - goto out; - - /* set the max native size to its max */ - request->dev = dev; - request->u.ata.command = ATA_SET_MAX_ADDRESS; - request->u.ata.count = 1; - request->u.ata.feature = 0; - request->flags = ATA_R_CONTROL; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 0; - ata_queue_request(request); - if (request->status & ATA_S_ERROR) - goto out; - - /* refresh geometry from drive */ - ata_getparam(device_get_softc(dev), 0); - ad_get_geometry(dev); - if (1 | bootverbose) - device_printf(dev, "NEW %ju sectors [%juC/%dH/%dS]\n", adp->total_secs, - adp->total_secs / (adp->heads * adp->sectors), - adp->heads, adp->sectors); -out: - ata_free_request(request); -} - -static void -ad_describe(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct ad_softc *adp = device_get_ivars(dev); - u_int8_t *marker, vendor[64], product[64]; - - /* try to separate the ATA model string into vendor and model parts */ - if ((marker = strchr(atadev->param.model, ' ')) || - (marker = strchr(atadev->param.model, '-'))) { - int len = (marker - atadev->param.model); - - strncpy(vendor, atadev->param.model, len); - vendor[len++] = 0; - strcat(vendor, " "); - strncpy(product, atadev->param.model + len, 40 - len); - vendor[40 - len] = 0; - } - else { - if (!strncmp(atadev->param.model, "ST", 2)) - strcpy(vendor, "Seagate "); - else if (!strncmp(atadev->param.model, "HDS", 3)) - strcpy(vendor, "Hitachi "); - else - strcpy(vendor, ""); - strncpy(product, atadev->param.model, 40); - } - - device_printf(dev, "%juMB <%s%s %.8s> at ata%d-%s %s%s %s\n", - adp->total_secs / (1048576 / DEV_BSIZE), - vendor, product, atadev->param.revision, - device_get_unit(ch->dev), ata_unit2str(atadev), - (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - if (bootverbose) { - device_printf(dev, "%ju sectors [%juC/%dH/%dS] " - "%d sectors/interrupt %d depth queue\n", adp->total_secs, - adp->total_secs / (adp->heads * adp->sectors), - adp->heads, adp->sectors, atadev->max_iosize / DEV_BSIZE, - adp->num_tags + 1); - } -} - -static int -ad_version(u_int16_t version) -{ - int bit; - - if (version == 0xffff) - return 0; - for (bit = 15; bit >= 0; bit--) - if (version & (1< - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* structure describing an ATA disk */ -struct ad_softc { - u_int64_t total_secs; /* total # of sectors (LBA) */ - u_int8_t heads; - u_int8_t sectors; - u_int32_t transfersize; /* size of each transfer */ - int num_tags; /* number of tags supported */ - int flags; /* drive flags */ -#define AD_F_LABELLING 0x0001 -#define AD_F_CHS_USED 0x0002 -#define AD_F_32B_ENABLED 0x0004 -#define AD_F_TAG_ENABLED 0x0008 -#define AD_F_RAID_SUBDISK 0x0010 - - struct disk *disk; /* disklabel/slice stuff */ -}; - -extern devclass_t ad_devclass; - diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 5695bc8..6236f44 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -304,13 +304,11 @@ ata_dmaload(struct ata_request *request, void *addr, int *entries) else dspa.dmatab = request->dma->sg; -#ifdef ATA_CAM if (request->flags & ATA_R_DATA_IN_CCB) error = bus_dmamap_load_ccb(request->dma->data_tag, request->dma->data_map, request->ccb, ch->dma.setprd, &dspa, BUS_DMA_NOWAIT); else -#endif error = bus_dmamap_load(request->dma->data_tag, request->dma->data_map, request->data, request->bytecount, ch->dma.setprd, &dspa, BUS_DMA_NOWAIT); diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 6f83db7..4d526ca 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -783,9 +783,6 @@ static void ata_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); -#ifndef ATA_CAM - struct ata_device *atadev = device_get_softc(request->dev); -#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); @@ -803,39 +800,12 @@ ata_tf_write(struct ata_request *request) else { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); -#ifndef ATA_CAM - if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; - - if (atadev->param.atavalid & ATA_FLAG_54_58) { - heads = atadev->param.current_heads; - sectors = atadev->param.current_sectors; - } - 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, - (request->u.ata.lba / (sectors * heads))); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, - (request->u.ata.lba / (sectors * heads)) >> 8); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | - (((request->u.ata.lba% (sectors * heads)) / - sectors) & 0xf)); - } - else { -#endif 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 | ATA_DEV(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); -#ifndef ATA_CAM - } -#endif } } diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c index f47ea82..876e1ff 100644 --- a/sys/dev/ata/ata-pci.c +++ b/sys/dev/ata/ata-pci.c @@ -698,21 +698,6 @@ ata_pcichannel_resume(device_t dev) return ata_resume(dev); } - -#ifndef ATA_CAM -static int -ata_pcichannel_locking(device_t dev, int mode) -{ - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); - - if (ctlr->locking) - return ctlr->locking(dev, mode); - else - return ch->unit; -} -#endif - static void ata_pcichannel_reset(device_t dev) { @@ -768,9 +753,6 @@ static device_method_t ata_pcichannel_methods[] = { /* ATA methods */ DEVMETHOD(ata_setmode, ata_pcichannel_setmode), DEVMETHOD(ata_getrev, ata_pcichannel_getrev), -#ifndef ATA_CAM - DEVMETHOD(ata_locking, ata_pcichannel_locking), -#endif DEVMETHOD(ata_reset, ata_pcichannel_reset), DEVMETHOD_END diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index d918528..d1eb0e9 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -62,9 +62,6 @@ struct ata_pci_controller { int (*ch_detach)(device_t); int (*ch_suspend)(device_t); int (*ch_resume)(device_t); -#ifndef ATA_CAM - int (*locking)(device_t, int); -#endif void (*reset)(device_t); int (*setmode)(device_t, int, int); int (*getrev)(device_t, int); diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c index d18f9c1..30a8b7c7 100644 --- a/sys/dev/ata/ata-queue.c +++ b/sys/dev/ata/ata-queue.c @@ -43,473 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include -#ifndef ATA_CAM -/* prototypes */ -static void ata_completed(void *, int); -static void ata_sort_queue(struct ata_channel *ch, struct ata_request *request); -static const char *ata_skey2str(u_int8_t); -#endif - -#ifndef ATA_CAM -void -ata_queue_request(struct ata_request *request) -{ - struct ata_channel *ch; - struct ata_device *atadev = device_get_softc(request->dev); - - /* treat request as virgin (this might be an ATA_R_REQUEUE) */ - request->result = request->status = request->error = 0; - - /* Prepare paramers required by low-level code. */ - request->unit = atadev->unit; - if (!(request->parent = device_get_parent(request->dev))) { - request->result = ENXIO; - if (request->callback) - (request->callback)(request); - return; - } - if ((atadev->param.config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) - request->flags |= ATA_R_ATAPI16; - if ((atadev->param.config & ATA_DRQ_MASK) == ATA_DRQ_INTR) - request->flags |= ATA_R_ATAPI_INTR; - if ((request->flags & ATA_R_ATAPI) == 0) - ata_modify_if_48bit(request); - ch = device_get_softc(request->parent); - callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); - if (!request->callback && !(request->flags & ATA_R_REQUEUE)) - sema_init(&request->done, 0, "ATA request done"); - - /* in ATA_STALL_QUEUE state we call HW directly */ - if ((ch->state & ATA_STALL_QUEUE) && (request->flags & ATA_R_CONTROL)) { - mtx_lock(&ch->state_mtx); - ch->running = request; - if (ch->hw.begin_transaction(request) == ATA_OP_FINISHED) { - ch->running = NULL; - if (!request->callback) - sema_destroy(&request->done); - mtx_unlock(&ch->state_mtx); - return; - } - mtx_unlock(&ch->state_mtx); - } - /* otherwise put request on the locked queue at the specified location */ - else { - mtx_lock(&ch->queue_mtx); - if (request->flags & ATA_R_AT_HEAD) - TAILQ_INSERT_HEAD(&ch->ata_queue, request, chain); - else if (request->flags & ATA_R_ORDERED) - ata_sort_queue(ch, request); - else - TAILQ_INSERT_TAIL(&ch->ata_queue, request, chain); - mtx_unlock(&ch->queue_mtx); - ATA_DEBUG_RQ(request, "queued"); - ata_start(ch->dev); - } - - /* if this is a requeued request callback/sleep we're done */ - if (request->flags & ATA_R_REQUEUE) - return; - - /* if this is not a callback wait until request is completed */ - if (!request->callback) { - ATA_DEBUG_RQ(request, "wait for completion"); - if (!dumping && - sema_timedwait(&request->done, request->timeout * hz * 4)) { - callout_drain(&request->callout); - device_printf(request->dev, - "WARNING - %s taskqueue timeout " - "- completing request directly\n", - ata_cmd2str(request)); - request->flags |= ATA_R_DANGER1; - ata_completed(request, 0); - } - sema_destroy(&request->done); - } -} -#endif - -#ifndef ATA_CAM -int -ata_controlcmd(device_t dev, u_int8_t command, u_int16_t feature, - u_int64_t lba, u_int16_t count) -{ - struct ata_device *atadev = device_get_softc(dev); - struct ata_request *request = ata_alloc_request(); - int error = ENOMEM; - - if (request) { - request->dev = dev; - request->u.ata.command = command; - request->u.ata.lba = lba; - request->u.ata.count = count; - request->u.ata.feature = feature; - request->flags = ATA_R_CONTROL; - if (atadev->spindown_state) { - device_printf(dev, "request while spun down, starting.\n"); - atadev->spindown_state = 0; - request->timeout = MAX(ATA_REQUEST_TIMEOUT, 31); - } else { - request->timeout = ATA_REQUEST_TIMEOUT; - } - request->retries = 0; - ata_queue_request(request); - error = request->result; - ata_free_request(request); - } - return error; -} -#endif - -#ifndef ATA_CAM -int -ata_atapicmd(device_t dev, u_int8_t *ccb, caddr_t data, - int count, int flags, int timeout) -{ - struct ata_request *request = ata_alloc_request(); - int error = ENOMEM; - - if (request) { - request->dev = dev; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = data; - request->bytecount = count; - request->transfersize = min(request->bytecount, 65534); - request->flags = flags | ATA_R_ATAPI; - request->timeout = timeout; - request->retries = 0; - ata_queue_request(request); - error = request->result; - ata_free_request(request); - } - return error; -} -#endif - -#ifndef ATA_CAM -void -ata_start(device_t dev) -{ - struct ata_channel *ch = device_get_softc(dev); - struct ata_request *request; - struct ata_composite *cptr; - int dependencies = 0; - - /* if we have a request on the queue try to get it running */ - mtx_lock(&ch->queue_mtx); - if ((request = TAILQ_FIRST(&ch->ata_queue))) { - - /* we need the locking function to get the lock for this channel */ - if (ATA_LOCKING(dev, ATA_LF_LOCK) == ch->unit) { - - /* check for composite dependencies */ - if ((cptr = request->composite)) { - mtx_lock(&cptr->lock); - if ((request->flags & ATA_R_WRITE) && - (cptr->wr_depend & cptr->rd_done) != cptr->wr_depend) { - dependencies = 1; - } - mtx_unlock(&cptr->lock); - } - - /* check we are in the right state and has no dependencies */ - mtx_lock(&ch->state_mtx); - if (ch->state == ATA_IDLE && !dependencies) { - ATA_DEBUG_RQ(request, "starting"); - TAILQ_REMOVE(&ch->ata_queue, request, chain); - ch->running = request; - ch->state = ATA_ACTIVE; - - /* if we are the freezing point release it */ - if (ch->freezepoint == request) - ch->freezepoint = NULL; - - if (ch->hw.begin_transaction(request) == ATA_OP_FINISHED) { - ch->running = NULL; - ch->state = ATA_IDLE; - mtx_unlock(&ch->state_mtx); - mtx_unlock(&ch->queue_mtx); - ATA_LOCKING(dev, ATA_LF_UNLOCK); - ata_finish(request); - return; - } - } - mtx_unlock(&ch->state_mtx); - } - } - mtx_unlock(&ch->queue_mtx); - if (dumping) { - while (ch->running) { - ata_interrupt(ch); - DELAY(10); - } - } -} -#endif - -#ifndef ATA_CAM -void -ata_finish(struct ata_request *request) -{ - struct ata_channel *ch = device_get_softc(request->parent); - - /* - * if in ATA_STALL_QUEUE state or request has ATA_R_DIRECT flags set - * we need to call ata_complete() directly here (no taskqueue involvement) - */ - if (dumping || - (ch->state & ATA_STALL_QUEUE) || (request->flags & ATA_R_DIRECT)) { - ATA_DEBUG_RQ(request, "finish directly"); - ata_completed(request, 0); - } - else { - /* put request on the proper taskqueue for completion */ - if (request->bio && !(request->flags & (ATA_R_THREAD | ATA_R_TIMEOUT))){ - ATA_DEBUG_RQ(request, "finish bio_taskqueue"); - bio_taskqueue(request->bio, (bio_task_t *)ata_completed, request); - } - else { - TASK_INIT(&request->task, 0, ata_completed, request); - ATA_DEBUG_RQ(request, "finish taskqueue_swi"); - taskqueue_enqueue(taskqueue_swi, &request->task); - } - } -} -#endif - -#ifndef ATA_CAM -static void -ata_completed(void *context, int dummy) -{ - struct ata_request *request = (struct ata_request *)context; - struct ata_channel *ch = device_get_softc(request->parent); - struct ata_device *atadev = device_get_softc(request->dev); - struct ata_composite *composite; - - if (request->flags & ATA_R_DANGER2) { - device_printf(request->dev, - "WARNING - %s freeing taskqueue zombie request\n", - ata_cmd2str(request)); - request->flags &= ~(ATA_R_DANGER1 | ATA_R_DANGER2); - ata_free_request(request); - return; - } - if (request->flags & ATA_R_DANGER1) - request->flags |= ATA_R_DANGER2; - - ATA_DEBUG_RQ(request, "completed entered"); - - /* if we had a timeout, reinit channel and deal with the falldown */ - if (request->flags & ATA_R_TIMEOUT) { - /* - * if the channel is still present and - * reinit succeeds and - * the device doesn't get detached and - * there are retries left we reinject this request - */ - if (ch && !ata_reinit(ch->dev) && !request->result && - (request->retries-- > 0)) { - if (!(request->flags & ATA_R_QUIET)) { - device_printf(request->dev, - "TIMEOUT - %s retrying (%d retr%s left)", - ata_cmd2str(request), request->retries, - request->retries == 1 ? "y" : "ies"); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - } - request->flags &= ~(ATA_R_TIMEOUT | ATA_R_DEBUG); - request->flags |= (ATA_R_AT_HEAD | ATA_R_REQUEUE); - ATA_DEBUG_RQ(request, "completed reinject"); - ata_queue_request(request); - return; - } - - /* ran out of good intentions so finish with error */ - if (!request->result) { - if (!(request->flags & ATA_R_QUIET)) { - if (request->dev) { - device_printf(request->dev, "FAILURE - %s timed out", - ata_cmd2str(request)); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - } - } - request->result = EIO; - } - } - else if (!(request->flags & ATA_R_ATAPI) ){ - /* if this is a soft ECC error warn about it */ - /* XXX SOS we could do WARF here */ - if ((request->status & (ATA_S_CORR | ATA_S_ERROR)) == ATA_S_CORR) { - device_printf(request->dev, - "WARNING - %s soft error (ECC corrected)", - ata_cmd2str(request)); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - } - - /* if this is a UDMA CRC error we reinject if there are retries left */ - if (request->flags & ATA_R_DMA && request->error & ATA_E_ICRC) { - if (request->retries-- > 0) { - device_printf(request->dev, - "WARNING - %s UDMA ICRC error (retrying request)", - ata_cmd2str(request)); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - request->flags |= (ATA_R_AT_HEAD | ATA_R_REQUEUE); - ata_queue_request(request); - return; - } - } - } - - switch (request->flags & ATA_R_ATAPI) { - - /* ATA errors */ - default: - if (!request->result && request->status & ATA_S_ERROR) { - if (!(request->flags & ATA_R_QUIET)) { - device_printf(request->dev, - "FAILURE - %s status=%b error=%b", - ata_cmd2str(request), - request->status, "\20\10BUSY\7READY\6DMA_READY" - "\5DSC\4DRQ\3CORRECTABLE\2INDEX\1ERROR", - request->error, "\20\10ICRC\7UNCORRECTABLE" - "\6MEDIA_CHANGED\5NID_NOT_FOUND" - "\4MEDIA_CHANGE_REQEST" - "\3ABORTED\2NO_MEDIA\1ILLEGAL_LENGTH"); - if ((request->flags & ATA_R_DMA) && request->dma && - (request->dma->status & ATA_BMSTAT_ERROR)) - printf(" dma=0x%02x", request->dma->status); - if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%ju", request->u.ata.lba); - printf("\n"); - } - request->result = EIO; - } - break; - - /* ATAPI errors */ - case ATA_R_ATAPI: - /* skip if result already set */ - if (request->result) - break; - - /* if we have a sensekey -> request sense from device */ - if ((request->error & ATA_E_ATAPI_SENSE_MASK) && - (request->u.atapi.ccb[0] != ATAPI_REQUEST_SENSE)) { - static u_int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0, - sizeof(struct atapi_sense), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - request->u.atapi.saved_cmd = request->u.atapi.ccb[0]; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = (caddr_t)&request->u.atapi.sense; - request->bytecount = sizeof(struct atapi_sense); - request->donecount = 0; - request->transfersize = sizeof(struct atapi_sense); - request->timeout = ATA_REQUEST_TIMEOUT; - request->flags &= (ATA_R_ATAPI | ATA_R_QUIET | ATA_R_DEBUG); - request->flags |= (ATA_R_READ | ATA_R_AT_HEAD | ATA_R_REQUEUE); - ATA_DEBUG_RQ(request, "autoissue request sense"); - ata_queue_request(request); - return; - } - - switch (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK) { - case ATA_SENSE_RECOVERED_ERROR: - device_printf(request->dev, "WARNING - %s recovered error\n", - ata_cmd2str(request)); - /* FALLTHROUGH */ - - case ATA_SENSE_NO_SENSE: - request->result = 0; - break; - - case ATA_SENSE_NOT_READY: - request->result = EBUSY; - break; - - case ATA_SENSE_UNIT_ATTENTION: - atadev->flags |= ATA_D_MEDIA_CHANGED; - request->result = EIO; - break; - - default: - request->result = EIO; - if (request->flags & ATA_R_QUIET) - break; - - device_printf(request->dev, - "FAILURE - %s %s asc=0x%02x ascq=0x%02x ", - ata_cmd2str(request), ata_skey2str( - (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK)), - request->u.atapi.sense.asc, - request->u.atapi.sense.ascq); - if (request->u.atapi.sense.specific & ATA_SENSE_SPEC_VALID) - printf("sks=0x%02x 0x%02x 0x%02x\n", - request->u.atapi.sense.specific & ATA_SENSE_SPEC_MASK, - request->u.atapi.sense.specific1, - request->u.atapi.sense.specific2); - else - printf("\n"); - } - - if (!request->result && - (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK || - request->error)) - request->result = EIO; - } - - ATA_DEBUG_RQ(request, "completed callback/wakeup"); - - /* if we are part of a composite operation we need to maintain progress */ - if ((composite = request->composite)) { - int index = 0; - - mtx_lock(&composite->lock); - - /* update whats done */ - if (request->flags & ATA_R_READ) - composite->rd_done |= (1 << request->this); - if (request->flags & ATA_R_WRITE) - composite->wr_done |= (1 << request->this); - - /* find ready to go dependencies */ - if (composite->wr_depend && - (composite->rd_done & composite->wr_depend)==composite->wr_depend && - (composite->wr_needed & (~composite->wr_done))) { - index = composite->wr_needed & ~composite->wr_done; - } - - mtx_unlock(&composite->lock); - - /* if we have any ready candidates kick them off */ - if (index) { - int bit; - - for (bit = 0; bit < MAX_COMPOSITES; bit++) { - if (index & (1 << bit)) - ata_start(device_get_parent(composite->request[bit]->dev)); - } - } - } - - /* get results back to the initiator for this request */ - if (request->callback) - (request->callback)(request); - else - sema_post(&request->done); - - /* only call ata_start if channel is present */ - if (ch) - ata_start(ch->dev); -} -#endif - void ata_timeout(struct ata_request *request) { @@ -530,160 +63,14 @@ ata_timeout(struct ata_request *request) ch->dma.unload(request); ch->running = NULL; ch->state = ATA_IDLE; -#ifdef ATA_CAM ata_cam_end_transaction(ch->dev, request); -#endif mtx_unlock(&ch->state_mtx); -#ifndef ATA_CAM - ATA_LOCKING(ch->dev, ATA_LF_UNLOCK); - ata_finish(request); -#endif } else { mtx_unlock(&ch->state_mtx); } } -#ifndef ATA_CAM -void -ata_fail_requests(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_request *request, *tmp; - TAILQ_HEAD(, ata_request) fail_requests; - TAILQ_INIT(&fail_requests); - - /* grap all channel locks to avoid races */ - mtx_lock(&ch->queue_mtx); - mtx_lock(&ch->state_mtx); - - /* do we have any running request to care about ? */ - if ((request = ch->running) && (!dev || request->dev == dev)) { - callout_stop(&request->callout); - ch->running = NULL; - request->result = ENXIO; - TAILQ_INSERT_TAIL(&fail_requests, request, chain); - } - - /* fail all requests queued on this channel for device dev if !NULL */ - TAILQ_FOREACH_SAFE(request, &ch->ata_queue, chain, tmp) { - if (!dev || request->dev == dev) { - TAILQ_REMOVE(&ch->ata_queue, request, chain); - request->result = ENXIO; - TAILQ_INSERT_TAIL(&fail_requests, request, chain); - } - } - - mtx_unlock(&ch->state_mtx); - mtx_unlock(&ch->queue_mtx); - - /* finish up all requests collected above */ - TAILQ_FOREACH_SAFE(request, &fail_requests, chain, tmp) { - TAILQ_REMOVE(&fail_requests, request, chain); - ata_finish(request); - } -} -#endif - -#ifndef ATA_CAM -/* - * Rudely drop all requests queued to the channel of specified device. - * XXX: The requests are leaked, use only in fatal case. - */ -void -ata_drop_requests(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_request *request, *tmp; - - mtx_lock(&ch->queue_mtx); - TAILQ_FOREACH_SAFE(request, &ch->ata_queue, chain, tmp) { - TAILQ_REMOVE(&ch->ata_queue, request, chain); - request->result = ENXIO; - } - mtx_unlock(&ch->queue_mtx); -} -#endif - -#ifndef ATA_CAM -static u_int64_t -ata_get_lba(struct ata_request *request) -{ - if (request->flags & ATA_R_ATAPI) { - switch (request->u.atapi.ccb[0]) { - case ATAPI_READ_BIG: - case ATAPI_WRITE_BIG: - case ATAPI_READ_CD: - return (request->u.atapi.ccb[5]) | (request->u.atapi.ccb[4]<<8) | - (request->u.atapi.ccb[3]<<16)|(request->u.atapi.ccb[2]<<24); - case ATAPI_READ: - case ATAPI_WRITE: - return (request->u.atapi.ccb[4]) | (request->u.atapi.ccb[3]<<8) | - (request->u.atapi.ccb[2]<<16); - default: - return 0; - } - } - else - return request->u.ata.lba; -} -#endif - -#ifndef ATA_CAM -static void -ata_sort_queue(struct ata_channel *ch, struct ata_request *request) -{ - struct ata_request *this, *next; - - this = TAILQ_FIRST(&ch->ata_queue); - - /* if the queue is empty just insert */ - if (!this) { - if (request->composite) - ch->freezepoint = request; - TAILQ_INSERT_TAIL(&ch->ata_queue, request, chain); - return; - } - - /* dont sort frozen parts of the queue */ - if (ch->freezepoint) - this = ch->freezepoint; - - /* if position is less than head we add after tipping point */ - if (ata_get_lba(request) < ata_get_lba(this)) { - while ((next = TAILQ_NEXT(this, chain))) { - - /* have we reached the tipping point */ - if (ata_get_lba(next) < ata_get_lba(this)) { - - /* sort the insert */ - do { - if (ata_get_lba(request) < ata_get_lba(next)) - break; - this = next; - } while ((next = TAILQ_NEXT(this, chain))); - break; - } - this = next; - } - } - - /* we are after head so sort the insert before tipping point */ - else { - while ((next = TAILQ_NEXT(this, chain))) { - if (ata_get_lba(next) < ata_get_lba(this) || - ata_get_lba(request) < ata_get_lba(next)) - break; - this = next; - } - } - - if (request->composite) - ch->freezepoint = request; - TAILQ_INSERT_AFTER(&ch->ata_queue, this, request, chain); -} -#endif - const char * ata_cmd2str(struct ata_request *request) { @@ -797,29 +184,3 @@ ata_cmd2str(struct ata_request *request) sprintf(buffer, "unknown CMD (0x%02x)", request->u.ata.command); return buffer; } - -#ifndef ATA_CAM -static const char * -ata_skey2str(u_int8_t skey) -{ - switch (skey) { - case 0x00: return ("NO SENSE"); - case 0x01: return ("RECOVERED ERROR"); - case 0x02: return ("NOT READY"); - case 0x03: return ("MEDIUM ERROR"); - case 0x04: return ("HARDWARE ERROR"); - case 0x05: return ("ILLEGAL REQUEST"); - case 0x06: return ("UNIT ATTENTION"); - case 0x07: return ("DATA PROTECT"); - case 0x08: return ("BLANK CHECK"); - case 0x09: return ("VENDOR SPECIFIC"); - case 0x0a: return ("COPY ABORTED"); - case 0x0b: return ("ABORTED COMMAND"); - case 0x0c: return ("EQUAL"); - case 0x0d: return ("VOLUME OVERFLOW"); - case 0x0e: return ("MISCOMPARE"); - case 0x0f: return ("RESERVED"); - default: return("UNKNOWN"); - } -} -#endif diff --git a/sys/dev/ata/ata-raid-ddf.h b/sys/dev/ata/ata-raid-ddf.h deleted file mode 100644 index 30326bc..0000000 --- a/sys/dev/ata/ata-raid-ddf.h +++ /dev/null @@ -1,333 +0,0 @@ -/*- - * Copyright (c) 2008 Scott Long - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef ATA_RAID_DDF_H -#define ATA_RAID_DDF_H - -/* Definitions from the SNIA DDF spec, rev 1.2 */ - -#define DDF_HEADER_LENGTH 512 -struct ddf_header { - uint32_t Signature; -#define DDF_HEADER_SIGNATURE 0xde11de11 - uint32_t CRC; - uint8_t DDF_Header_GUID[24]; - uint8_t DDF_rev[8]; - uint32_t Sequence_Number; - uint32_t TimeStamp; - uint8_t Open_Flag; -#define DDF_HEADER_CLOSED 0x00 -#define DDF_HEADER_OPENED_MASK 0x0f -#define DDF_HEADER_OPEN_ANCHOR 0xff - uint8_t Foreign_Flag; - uint8_t Diskgrouping; - uint8_t pad1[13]; - uint8_t Header_ext[32]; - uint64_t Primary_Header_LBA; - uint64_t Secondary_Header_LBA; - uint8_t Header_Type; -#define DDF_HEADER_ANCHOR 0x00 -#define DDF_HEADER_PRIMARY 0x01 -#define DDF_HEADER_SECONDARY 0x02 - uint8_t pad2[3]; - uint32_t WorkSpace_Length; - uint64_t WorkSpace_LBA; - uint16_t Max_PD_Entries; - uint16_t Max_VD_Entries; - uint16_t Max_Partitions; - uint16_t Configuration_Record_Length; - uint16_t Max_Primary_Element_Entries; - uint8_t pad3[54]; - uint32_t cd_section; /* Controller_Data_Section */ - uint32_t cd_length; /* Controller_Data_Section_Length */ - uint32_t pdr_section; /* Physical_Drive_Records_Section */ - uint32_t pdr_length; /* Physical_Drive_Records_Length */ - uint32_t vdr_section; /* Virtual_Drive_Records_Section */ - uint32_t vdr_length; /* Virtual_Drive_Records_Length */ - uint32_t cr_section; /* Configuration_Records_Section */ - uint32_t cr_length; /* Configuration_Records_Length */ - uint32_t pdd_section; /* Physical_Drive_Data_Section */ - uint32_t pdd_length; /* Physical_Drive_Data_Length */ - uint32_t bbmlog_section; /* BBM_Log_Section */ - uint32_t bbmlog_length; /* BBM_Log_Section_Length */ - uint32_t Diagnostic_Space; - uint32_t Diagnostic_Space_Length; - uint32_t Vendor_Specific_Logs; - uint32_t Vendor_Specific_Logs_Length; - uint8_t pad4[256]; -} __packed; - -struct ddf_cd_record { - uint32_t Signature; -#define DDF_CONTROLLER_DATA_SIGNATURE 0xad111111 - uint32_t CRC; - uint8_t Controller_GUID[24]; - struct { - uint16_t Vendor_ID; - uint16_t Device_ID; - uint16_t SubVendor_ID; - uint16_t SubDevice_ID; - } Controller_Type __packed; - uint8_t Product_ID[16]; - uint8_t pad1[8]; - uint8_t Controller_Data[448]; -} __packed; - -struct ddf_device_scsi { - uint8_t Lun; - uint8_t Id; - uint8_t Channel; - uint8_t Path_Flags; -#define DDF_DEVICE_SCSI_FLAG_BROKEN (1 << 7) -} __packed; - -struct ddf_device_sas { - uint64_t Initiator_Path; -} __packed; - -union ddf_pathinfo { - struct { - struct ddf_device_scsi Path0; - struct ddf_device_scsi Path1; - uint8_t pad[10]; - } __packed scsi; - struct { - struct ddf_device_sas Path0; - struct ddf_device_sas Path1; - uint8_t Path0_Flags; - uint8_t Path1_Flags; -#define DDF_DEVICE_SAS_FLAG_BROKEN (1 << 7) - } __packed sas; -} __packed; - -struct ddf_pd_entry { - uint8_t PD_GUID[24]; - uint32_t PD_Reference; - uint16_t PD_Type; -#define DDF_PDE_GUID_FORCE (1 << 0) -#define DDF_PDE_PARTICIPATING (1 << 1) -#define DDF_PDE_GLOBAL_SPARE (1 << 2) -#define DDF_PDE_CONFIG_SPARE (1 << 3) -#define DDF_PDE_FOREIGN (1 << 4) -#define DDF_PDE_LEGACY (1 << 5) -#define DDF_PDE_TYPE_MASK (0x0f << 12) -#define DDF_PDE_UNKNOWN (0x00 << 12) -#define DDF_PDE_SCSI (0x01 << 12) -#define DDF_PDE_SAS (0x02 << 12) -#define DDF_PDE_SATA (0x03 << 12) -#define DDF_PDE_FC (0x04 << 12) - uint16_t PD_State; -#define DDF_PDE_ONLINE (1 << 0) -#define DDF_PDE_FAILED (1 << 1) -#define DDF_PDE_REBUILD (1 << 2) -#define DDF_PDE_TRANSITION (1 << 3) -#define DDF_PDE_PFA (1 << 4) -#define DDF_PDE_UNRECOVERED (1 << 5) -#define DDF_PDE_MISSING (1 << 6) - uint64_t Configured_Size; - union ddf_pathinfo Path_Information; - uint8_t pad1[6]; -} __packed; - -struct ddf_pd_record { - uint32_t Signature; -#define DDF_PDR_SIGNATURE 0x22222222 - uint32_t CRC; - uint16_t Populated_PDEs; - uint16_t Max_PDE_Supported; - uint8_t pad1[52]; - struct ddf_pd_entry entry[0]; -} __packed; - -struct ddf_vd_entry { - uint8_t VD_GUID[24]; - uint16_t VD_Number; - uint8_t pad1[2]; - uint16_t VD_Type; -#define DDF_VDE_SHARED (1 << 0) -#define DDF_VDE_ENFORCE_GROUP (1 << 1) -#define DDF_VDE_UNICODE_NAME (1 << 2) -#define DDF_VDE_OWNER_ID_VALID (1 << 3) - uint16_t Controller_GUID_CRC; - uint8_t VD_State; -#define DDF_VDE_OPTIMAL 0x00 -#define DDF_VDE_DEGRADED 0x01 -#define DDF_VDE_DELETED 0x02 -#define DDF_VDE_MISSING 0x03 -#define DDF_VDE_FAILED 0x04 -#define DDF_VDE_PARTIAL 0x05 -#define DDF_VDE_STATE_MASK 0x07 -#define DDF_VDE_MORPH (1 << 3) -#define DDF_VDE_DIRTY (1 << 4) - uint8_t Init_State; -#define DDF_VDE_UNINTIALIZED 0x00 -#define DDF_VDE_INIT_QUICK 0x01 -#define DDF_VDE_INIT_FULL 0x02 -#define DDF_VDE_INIT_MASK 0x03 -#define DDF_VDE_UACCESS_RW 0x00 -#define DDF_VDE_UACCESS_RO 0x80 -#define DDF_VDE_UACCESS_BLOCKED 0xc0 -#define DDF_VDE_UACCESS_MASK 0xc0 - uint8_t pad2[14]; - uint8_t VD_Name[16]; -} __packed; - -struct ddf_vd_record { - uint32_t Signature; -#define DDF_VD_RECORD_SIGNATURE 0xdddddddd - uint32_t CRC; - uint16_t Populated_VDEs; - uint16_t Max_VDE_Supported; - uint8_t pad1[52]; - struct ddf_vd_entry entry[0]; -} __packed; - -#define DDF_CR_INVALID 0xffffffff - -struct ddf_vdc_record { - uint32_t Signature; -#define DDF_VDCR_SIGNATURE 0xeeeeeeee - uint32_t CRC; - uint8_t VD_GUID[24]; - uint32_t Timestamp; - uint32_t Sequence_Number; - uint8_t pad1[24]; - uint16_t Primary_Element_Count; - uint8_t Stripe_Size; - uint8_t Primary_RAID_Level; -#define DDF_VDCR_RAID0 0x00 -#define DDF_VDCR_RAID1 0x01 -#define DDF_VDCR_RAID3 0x03 -#define DDF_VDCR_RAID4 0x04 -#define DDF_VDCR_RAID5 0x05 -#define DDF_VDCR_RAID6 0x06 -#define DDF_VDCR_RAID1E 0x11 -#define DDF_VDCR_SINGLE 0x0f -#define DDF_VDCR_CONCAT 0x1f -#define DDF_VDCR_RAID5E 0x15 -#define DDF_VDCR_RAID5EE 0x25 - uint8_t RLQ; - uint8_t Secondary_Element_Count; - uint8_t Secondary_Element_Seq; - uint8_t Secondary_RAID_Level; - uint64_t Block_Count; - uint64_t VD_Size; - uint8_t pad2[8]; - uint32_t Associated_Spares[8]; - uint64_t Cache_Flags; -#define DDF_VDCR_CACHE_WB (1 << 0) -#define DDF_VDCR_CACHE_WB_ADAPTIVE (1 << 1) -#define DDF_VDCR_CACHE_RA (1 << 2) -#define DDF_VDCR_CACHE_RA_ADAPTIVE (1 << 3) -#define DDF_VDCR_CACHE_WCACHE_NOBATTERY (1 << 4) -#define DDF_VDCR_CACHE_WCACHE_ALLOW (1 << 5) -#define DDF_VDCR_CACHE_RCACHE_ALLOW (1 << 6) -#define DDF_VDCR_CACHE_VENDOR (1 << 7) - uint8_t BG_Rate; - uint8_t pad3[3]; - uint8_t pad4[52]; - uint8_t pad5[192]; - uint8_t V0[32]; - uint8_t V1[32]; - uint8_t V2[16]; - uint8_t V3[16]; - uint8_t Vendor_Scratch[32]; - uint32_t Physical_Disk_Sequence[0]; -} __packed; - -struct ddf_vuc_record { - uint32_t Signature; -#define DDF_VUCR_SIGNATURE 0x88888888 - uint32_t CRC; - uint8_t VD_GUID[24]; -} __packed; - -struct ddf_sa_entry { - uint8_t VD_GUID[24]; - uint16_t Secondary_Element; - uint8_t rsrvd2[6]; -} __packed; - -struct ddf_sa_record { - uint32_t Signature; -#define DDF_SA_SIGNATURE 0x55555555 - uint32_t CRC; - uint32_t Timestamp; - uint8_t pad1[7]; - uint8_t Spare_Type; -#define DDF_SAR_TYPE_DEDICATED (1 << 0) -#define DDF_SAR_TYPE_REVERTIBLE (1 << 1) -#define DDF_SAR_TYPE_ACTIVE (1 << 2) -#define DDF_SAR_TYPE_ENCL_AFFINITY (1 << 3) - uint16_t Populated_SAEs; - uint16_t MAX_SAE_Supported; - uint8_t pad2[8]; - struct ddf_sa_entry entry[0]; -} __packed; - -struct ddf_pdd_record { - uint32_t Signature; -#define DDF_PDD_SIGNATURE 0x33333333 - uint32_t CRC; - uint8_t PD_GUID[24]; - uint32_t PD_Reference; - uint8_t Forced_Ref_Flag; -#define DDF_PDD_FORCED_REF 0x01 - uint8_t Forced_PD_GUID_Flag; -#define DDF_PDD_FORCED_GUID 0x01 - uint8_t Vendor_Scratch[32]; - uint8_t pad2[442]; -} __packed; - -struct ddf_bbm_entry { - uint64_t Defective_Block_Start; - uint32_t Spare_Block_Offset; - uint16_t Remapped_Count; - uint8_t pad[2]; -}; - -struct ddf_bbm_log { - uint32_t Signature; -#define DDF_BBML_SIGNATURE 0xabadb10c - uint32_t CRC; - uint16_t Entry_Count; - uint32_t Spare_Block_Count; - uint8_t pad1[10]; - uint64_t First_Spare_LBA; - uint64_t Mapped_Block_Entry[0]; -} __packed; - -struct ddf_vendor_log { - uint32_t Signature; -#define DDF_VENDOR_LOG_SIGNATURE 0x01dbeef0 - uint32_t CRC; - uint64_t Log_Owner; - uint8_t pad1[16]; -} __packed; - -#endif diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c deleted file mode 100644 index 5b0595c..0000000 --- a/sys/dev/ata/ata-raid.c +++ /dev/null @@ -1,5462 +0,0 @@ -/*- - * Copyright (c) 2000 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ata.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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(struct ata_ioc_raid_status *status); -static int ata_raid_create(struct ata_ioc_raid_config *config); -static int ata_raid_delete(int array); -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); -static int ata_raid_wipe_metadata(struct ar_softc *rdp); -static int ata_raid_adaptec_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_ddf_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_hptv2_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_hptv2_write_meta(struct ar_softc *rdp); -static int ata_raid_hptv3_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_intel_write_meta(struct ar_softc *rdp); -static int ata_raid_ite_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_jmicron_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_jmicron_write_meta(struct ar_softc *rdp); -static int ata_raid_lsiv2_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_lsiv3_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_nvidia_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_promise_read_meta(device_t dev, struct ar_softc **raidp, int native); -static int ata_raid_promise_write_meta(struct ar_softc *rdp); -static int ata_raid_sii_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_sis_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_sis_write_meta(struct ar_softc *rdp); -static int ata_raid_via_read_meta(device_t dev, struct ar_softc **raidp); -static int ata_raid_via_write_meta(struct ar_softc *rdp); -static struct ata_request *ata_raid_init_request(device_t dev, struct ar_softc *rdp, struct bio *bio); -static int ata_raid_send_request(struct ata_request *request); -static int ata_raid_rw(device_t dev, u_int64_t lba, void *data, u_int bcount, int flags); -static char * ata_raid_format(struct ar_softc *rdp); -static char * ata_raid_type(struct ar_softc *rdp); -static char * ata_raid_flags(struct ar_softc *rdp); - -/* debugging only */ -static void ata_raid_print_meta(struct ar_softc *meta); -static void ata_raid_adaptec_print_meta(struct adaptec_raid_conf *meta); -static void ata_raid_ddf_print_meta(uint8_t *meta); -static void ata_raid_hptv2_print_meta(struct hptv2_raid_conf *meta); -static void ata_raid_hptv3_print_meta(struct hptv3_raid_conf *meta); -static void ata_raid_intel_print_meta(struct intel_raid_conf *meta); -static void ata_raid_ite_print_meta(struct ite_raid_conf *meta); -static void ata_raid_jmicron_print_meta(struct jmicron_raid_conf *meta); -static void ata_raid_lsiv2_print_meta(struct lsiv2_raid_conf *meta); -static void ata_raid_lsiv3_print_meta(struct lsiv3_raid_conf *meta); -static void ata_raid_nvidia_print_meta(struct nvidia_raid_conf *meta); -static void ata_raid_promise_print_meta(struct promise_raid_conf *meta); -static void ata_raid_sii_print_meta(struct sii_raid_conf *meta); -static void ata_raid_sis_print_meta(struct sis_raid_conf *meta); -static void ata_raid_via_print_meta(struct via_raid_conf *meta); - -/* internal vars */ -static struct ar_softc *ata_raid_arrays[MAX_ARRAYS]; -static MALLOC_DEFINE(M_AR, "ar_driver", "ATA PseudoRAID driver"); -static devclass_t ata_raid_sub_devclass; -static int testing = 0; - -/* device structures */ -static disk_strategy_t ata_raid_strategy; -static dumper_t ata_raid_dump; - -static void -ata_raid_attach(struct ar_softc *rdp, int writeback) -{ - char buffer[32]; - int disk; - - mtx_init(&rdp->lock, "ATA PseudoRAID metadata lock", NULL, MTX_DEF); - ata_raid_config_changed(rdp, writeback); - - /* sanitize arrays total_size % (width * interleave) == 0 */ - if (rdp->type == AR_T_RAID0 || rdp->type == AR_T_RAID01 || - rdp->type == AR_T_RAID5) { - rdp->total_sectors = (rdp->total_sectors/(rdp->interleave*rdp->width))* - (rdp->interleave * rdp->width); - sprintf(buffer, " (stripe %d KB)", - (rdp->interleave * DEV_BSIZE) / 1024); - } - else - buffer[0] = '\0'; - rdp->disk = disk_alloc(); - rdp->disk->d_strategy = ata_raid_strategy; - rdp->disk->d_dump = ata_raid_dump; - rdp->disk->d_name = "ar"; - rdp->disk->d_sectorsize = DEV_BSIZE; - rdp->disk->d_mediasize = (off_t)rdp->total_sectors * DEV_BSIZE; - rdp->disk->d_fwsectors = rdp->sectors; - rdp->disk->d_fwheads = rdp->heads; - rdp->disk->d_maxsize = 128 * DEV_BSIZE; - rdp->disk->d_drv1 = rdp; - rdp->disk->d_unit = rdp->lun; - /* we support flushing cache if all components support it */ - /* XXX: not all components can be connected at this point */ - rdp->disk->d_flags = DISKFLAG_CANFLUSHCACHE; - for (disk = 0; disk < rdp->total_disks; disk++) { - struct ata_device *atadev; - - if (rdp->disks[disk].dev == NULL) - continue; - if ((atadev = device_get_softc(rdp->disks[disk].dev)) == NULL) - continue; - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - continue; - rdp->disk->d_flags = 0; - break; - } - disk_create(rdp->disk, DISK_VERSION); - - printf("ar%d: %juMB <%s %s%s> status: %s\n", rdp->lun, - rdp->total_sectors / ((1024L * 1024L) / DEV_BSIZE), - ata_raid_format(rdp), ata_raid_type(rdp), - buffer, ata_raid_flags(rdp)); - - if (testing || bootverbose) - printf("ar%d: %ju sectors [%dC/%dH/%dS] <%s> subdisks defined as:\n", - rdp->lun, rdp->total_sectors, - rdp->cylinders, rdp->heads, rdp->sectors, rdp->name); - - for (disk = 0; disk < rdp->total_disks; disk++) { - printf("ar%d: disk%d ", rdp->lun, disk); - if (rdp->disks[disk].dev) { - if (rdp->disks[disk].flags & AR_DF_PRESENT) { - /* status of this disk in the array */ - if (rdp->disks[disk].flags & AR_DF_ONLINE) - printf("READY "); - else if (rdp->disks[disk].flags & AR_DF_SPARE) - printf("SPARE "); - else - printf("FREE "); - - /* what type of disk is this in the array */ - switch (rdp->type) { - case AR_T_RAID1: - case AR_T_RAID01: - if (disk < rdp->width) - printf("(master) "); - else - printf("(mirror) "); - } - - /* which physical disk is used */ - printf("using %s at ata%d-%s\n", - device_get_nameunit(rdp->disks[disk].dev), - device_get_unit(device_get_parent(rdp->disks[disk].dev)), - (((struct ata_device *) - device_get_softc(rdp->disks[disk].dev))->unit == - ATA_MASTER) ? "master" : "slave"); - } - else if (rdp->disks[disk].flags & AR_DF_ASSIGNED) - printf("DOWN\n"); - else - printf("INVALID no RAID config on this subdisk\n"); - } - else - printf("DOWN no device found for this subdisk\n"); - } -} - -static int -ata_raid_ioctl(u_long cmd, caddr_t data) -{ - struct ata_ioc_raid_status *status = (struct ata_ioc_raid_status *)data; - struct ata_ioc_raid_config *config = (struct ata_ioc_raid_config *)data; - int *lun = (int *)data; - int error = EOPNOTSUPP; - - switch (cmd) { - case IOCATARAIDSTATUS: - error = ata_raid_status(status); - break; - - case IOCATARAIDCREATE: - error = ata_raid_create(config); - break; - - case IOCATARAIDDELETE: - error = ata_raid_delete(*lun); - break; - - case IOCATARAIDADDSPARE: - error = ata_raid_addspare(config); - break; - - case IOCATARAIDREBUILD: - error = ata_raid_rebuild(*lun); - break; - } - return error; -} - -static int -ata_raid_flush(struct bio *bp) -{ - struct ar_softc *rdp = bp->bio_disk->d_drv1; - struct ata_request *request; - device_t dev; - int disk, error; - - error = 0; - bp->bio_pflags = 0; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if ((dev = rdp->disks[disk].dev) != NULL) - bp->bio_pflags++; - } - for (disk = 0; disk < rdp->total_disks; disk++) { - if ((dev = rdp->disks[disk].dev) == NULL) - continue; - if (!(request = ata_raid_init_request(dev, rdp, bp))) - return ENOMEM; - request->dev = dev; - request->u.ata.command = ATA_FLUSHCACHE; - request->u.ata.lba = 0; - request->u.ata.count = 0; - request->u.ata.feature = 0; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 0; - request->flags |= ATA_R_ORDERED | ATA_R_DIRECT; - ata_queue_request(request); - } - return 0; -} - -static void -ata_raid_strategy(struct bio *bp) -{ - struct ar_softc *rdp = bp->bio_disk->d_drv1; - struct ata_request *request; - caddr_t data; - u_int64_t blkno, lba, blk = 0; - int count, chunk, drv, par = 0, change = 0; - - if (bp->bio_cmd == BIO_FLUSH) { - int error; - - error = ata_raid_flush(bp); - if (error != 0) - biofinish(bp, NULL, error); - return; - } - - if (!(rdp->status & AR_S_READY) || - (bp->bio_cmd != BIO_READ && bp->bio_cmd != BIO_WRITE)) { - biofinish(bp, NULL, EIO); - return; - } - - bp->bio_resid = bp->bio_bcount; - for (count = howmany(bp->bio_bcount, DEV_BSIZE), - blkno = bp->bio_pblkno, data = bp->bio_data; - count > 0; - count -= chunk, blkno += chunk, data += (chunk * DEV_BSIZE)) { - - switch (rdp->type) { - case AR_T_RAID1: - drv = 0; - lba = blkno; - chunk = count; - break; - - case AR_T_JBOD: - case AR_T_SPAN: - drv = 0; - lba = blkno; - while (lba >= rdp->disks[drv].sectors) - lba -= rdp->disks[drv++].sectors; - chunk = min(rdp->disks[drv].sectors - lba, count); - break; - - case AR_T_RAID0: - case AR_T_RAID01: - chunk = blkno % rdp->interleave; - drv = (blkno / rdp->interleave) % rdp->width; - lba = (((blkno/rdp->interleave)/rdp->width)*rdp->interleave)+chunk; - chunk = min(count, rdp->interleave - chunk); - break; - - case AR_T_RAID5: - drv = (blkno / rdp->interleave) % (rdp->width - 1); - par = rdp->width - 1 - - (blkno / (rdp->interleave * (rdp->width - 1))) % rdp->width; - if (drv >= par) - drv++; - lba = ((blkno/rdp->interleave)/(rdp->width-1))*(rdp->interleave) + - ((blkno%(rdp->interleave*(rdp->width-1)))%rdp->interleave); - chunk = min(count, rdp->interleave - (lba % rdp->interleave)); - break; - - default: - printf("ar%d: unknown array type in ata_raid_strategy\n", rdp->lun); - biofinish(bp, NULL, EIO); - return; - } - - /* offset on all but "first on HPTv2" */ - if (!(drv == 0 && rdp->format == AR_F_HPTV2_RAID)) - lba += rdp->offset_sectors; - - if (!(request = ata_raid_init_request(rdp->disks[drv].dev, rdp, bp))) { - biofinish(bp, NULL, EIO); - return; - } - request->data = data; - request->bytecount = chunk * DEV_BSIZE; - request->u.ata.lba = lba; - request->u.ata.count = request->bytecount / DEV_BSIZE; - - switch (rdp->type) { - case AR_T_JBOD: - case AR_T_SPAN: - case AR_T_RAID0: - if (((rdp->disks[drv].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) == - (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[drv].dev)) { - rdp->disks[drv].flags &= ~AR_DF_ONLINE; - ata_raid_config_changed(rdp, 1); - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - request->this = drv; - request->dev = rdp->disks[drv].dev; - ata_raid_send_request(request); - break; - - case AR_T_RAID1: - case AR_T_RAID01: - if ((rdp->disks[drv].flags & - (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) && - !rdp->disks[drv].dev) { - rdp->disks[drv].flags &= ~AR_DF_ONLINE; - change = 1; - } - if ((rdp->disks[drv + rdp->width].flags & - (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) && - !rdp->disks[drv + rdp->width].dev) { - rdp->disks[drv + rdp->width].flags &= ~AR_DF_ONLINE; - change = 1; - } - if (change) - ata_raid_config_changed(rdp, 1); - if (!(rdp->status & AR_S_READY)) { - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - - if (rdp->status & AR_S_REBUILDING) - blk = ((lba / rdp->interleave) * rdp->width) * rdp->interleave + - (rdp->interleave * (drv % rdp->width)) + - lba % rdp->interleave; - - if (bp->bio_cmd == BIO_READ) { - int src_online = - (rdp->disks[drv].flags & AR_DF_ONLINE); - int mir_online = - (rdp->disks[drv+rdp->width].flags & AR_DF_ONLINE); - - /* if mirror gone or close to last access on source */ - if (!mir_online || - ((src_online) && - bp->bio_pblkno >= - (rdp->disks[drv].last_lba - AR_PROXIMITY) && - bp->bio_pblkno <= - (rdp->disks[drv].last_lba + AR_PROXIMITY))) { - rdp->toggle = 0; - } - /* if source gone or close to last access on mirror */ - else if (!src_online || - ((mir_online) && - bp->bio_pblkno >= - (rdp->disks[drv+rdp->width].last_lba-AR_PROXIMITY) && - bp->bio_pblkno <= - (rdp->disks[drv+rdp->width].last_lba+AR_PROXIMITY))) { - drv += rdp->width; - rdp->toggle = 1; - } - /* not close to any previous access, toggle */ - else { - if (rdp->toggle) - rdp->toggle = 0; - else { - drv += rdp->width; - rdp->toggle = 1; - } - } - - if ((rdp->status & AR_S_REBUILDING) && - (blk <= rdp->rebuild_lba) && - ((blk + chunk) > rdp->rebuild_lba)) { - struct ata_composite *composite; - struct ata_request *rebuild; - int this; - - /* figure out what part to rebuild */ - if (drv < rdp->width) - this = drv + rdp->width; - else - this = drv - rdp->width; - - /* do we have a spare to rebuild on ? */ - if (rdp->disks[this].flags & AR_DF_SPARE) { - if ((composite = ata_alloc_composite())) { - if ((rebuild = ata_raid_init_request( - rdp->disks[this].dev, rdp, bp))) { - rdp->rebuild_lba = blk + chunk; - rebuild->data = request->data; - rebuild->bytecount = request->bytecount; - rebuild->u.ata.lba = request->u.ata.lba; - rebuild->u.ata.count = request->u.ata.count; - rebuild->this = this; - rebuild->flags &= ~ATA_R_READ; - rebuild->flags |= ATA_R_WRITE; - mtx_init(&composite->lock, - "ATA PseudoRAID rebuild lock", - NULL, MTX_DEF); - composite->residual = request->bytecount; - composite->rd_needed |= (1 << drv); - composite->wr_depend |= (1 << drv); - composite->wr_needed |= (1 << this); - composite->request[drv] = request; - composite->request[this] = rebuild; - request->composite = composite; - rebuild->composite = composite; - ata_raid_send_request(rebuild); - } - else { - ata_free_composite(composite); - printf("DOH! ata_alloc_request failed!\n"); - } - } - else { - printf("DOH! ata_alloc_composite failed!\n"); - } - } - else if (rdp->disks[this].flags & AR_DF_ONLINE) { - /* - * if we got here we are a chunk of a RAID01 that - * does not need a rebuild, but we need to increment - * the rebuild_lba address to get the rebuild to - * move to the next chunk correctly - */ - rdp->rebuild_lba = blk + chunk; - } - else - printf("DOH! we didn't find the rebuild part\n"); - } - } - if (bp->bio_cmd == BIO_WRITE) { - if ((rdp->disks[drv+rdp->width].flags & AR_DF_ONLINE) || - ((rdp->status & AR_S_REBUILDING) && - (rdp->disks[drv+rdp->width].flags & AR_DF_SPARE) && - ((blk < rdp->rebuild_lba) || - ((blk <= rdp->rebuild_lba) && - ((blk + chunk) > rdp->rebuild_lba))))) { - if ((rdp->disks[drv].flags & AR_DF_ONLINE) || - ((rdp->status & AR_S_REBUILDING) && - (rdp->disks[drv].flags & AR_DF_SPARE) && - ((blk < rdp->rebuild_lba) || - ((blk <= rdp->rebuild_lba) && - ((blk + chunk) > rdp->rebuild_lba))))) { - struct ata_request *mirror; - struct ata_composite *composite; - int this = drv + rdp->width; - - if ((composite = ata_alloc_composite())) { - if ((mirror = ata_raid_init_request( - rdp->disks[this].dev, rdp, bp))) { - if ((blk <= rdp->rebuild_lba) && - ((blk + chunk) > rdp->rebuild_lba)) - rdp->rebuild_lba = blk + chunk; - mirror->data = request->data; - mirror->bytecount = request->bytecount; - mirror->u.ata.lba = request->u.ata.lba; - mirror->u.ata.count = request->u.ata.count; - mirror->this = this; - mtx_init(&composite->lock, - "ATA PseudoRAID mirror lock", - NULL, MTX_DEF); - composite->residual = request->bytecount; - composite->wr_needed |= (1 << drv); - composite->wr_needed |= (1 << this); - composite->request[drv] = request; - composite->request[this] = mirror; - request->composite = composite; - mirror->composite = composite; - ata_raid_send_request(mirror); - rdp->disks[this].last_lba = - bp->bio_pblkno + chunk; - } - else { - ata_free_composite(composite); - printf("DOH! ata_alloc_request failed!\n"); - } - } - else { - printf("DOH! ata_alloc_composite failed!\n"); - } - } - else - drv += rdp->width; - } - } - request->this = drv; - request->dev = rdp->disks[request->this].dev; - ata_raid_send_request(request); - rdp->disks[request->this].last_lba = bp->bio_pblkno + chunk; - break; - - case AR_T_RAID5: - if (((rdp->disks[drv].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) == - (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[drv].dev)) { - rdp->disks[drv].flags &= ~AR_DF_ONLINE; - change = 1; - } - if (((rdp->disks[par].flags & (AR_DF_PRESENT|AR_DF_ONLINE)) == - (AR_DF_PRESENT|AR_DF_ONLINE) && !rdp->disks[par].dev)) { - rdp->disks[par].flags &= ~AR_DF_ONLINE; - change = 1; - } - if (change) - ata_raid_config_changed(rdp, 1); - if (!(rdp->status & AR_S_READY)) { - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - if (rdp->status & AR_S_DEGRADED) { - /* do the XOR game if possible */ - } - else { - request->this = drv; - request->dev = rdp->disks[request->this].dev; - if (bp->bio_cmd == BIO_READ) { - ata_raid_send_request(request); - } - if (bp->bio_cmd == BIO_WRITE) { - ata_raid_send_request(request); - // sikre at læs-modify-skriv til hver disk er atomarisk. - // par kopi af request - // læse orgdata fra drv - // skriv nydata til drv - // læse parorgdata fra par - // skriv orgdata xor parorgdata xor nydata til par - } - } - break; - - default: - printf("ar%d: unknown array type in ata_raid_strategy\n", rdp->lun); - } - } -} - -static void -ata_raid_done(struct ata_request *request) -{ - struct ar_softc *rdp = request->driver; - struct ata_composite *composite = NULL; - struct bio *bp = request->bio; - int i, mirror, finished = 0; - - if (bp->bio_cmd == BIO_FLUSH) { - if (bp->bio_error == 0) - bp->bio_error = request->result; - ata_free_request(request); - if (--bp->bio_pflags == 0) - biodone(bp); - return; - } - - switch (rdp->type) { - case AR_T_JBOD: - case AR_T_SPAN: - case AR_T_RAID0: - if (request->result) { - rdp->disks[request->this].flags &= ~AR_DF_ONLINE; - ata_raid_config_changed(rdp, 1); - bp->bio_error = request->result; - finished = 1; - } - else { - bp->bio_resid -= request->donecount; - if (!bp->bio_resid) - finished = 1; - } - break; - - case AR_T_RAID1: - case AR_T_RAID01: - if (request->this < rdp->width) - mirror = request->this + rdp->width; - else - mirror = request->this - rdp->width; - if (request->result) { - rdp->disks[request->this].flags &= ~AR_DF_ONLINE; - ata_raid_config_changed(rdp, 1); - } - if (rdp->status & AR_S_READY) { - u_int64_t blk = 0; - - if (rdp->status & AR_S_REBUILDING) - blk = ((request->u.ata.lba / rdp->interleave) * rdp->width) * - rdp->interleave + (rdp->interleave * - (request->this % rdp->width)) + - request->u.ata.lba % rdp->interleave; - - if (bp->bio_cmd == BIO_READ) { - - /* is this a rebuild composite */ - if ((composite = request->composite)) { - mtx_lock(&composite->lock); - - /* handle the read part of a rebuild composite */ - if (request->flags & ATA_R_READ) { - - /* if read failed array is now broken */ - if (request->result) { - rdp->disks[request->this].flags &= ~AR_DF_ONLINE; - ata_raid_config_changed(rdp, 1); - bp->bio_error = request->result; - rdp->rebuild_lba = blk; - finished = 1; - } - - /* good data, update how far we've gotten */ - else { - bp->bio_resid -= request->donecount; - composite->residual -= request->donecount; - if (!composite->residual) { - if (composite->wr_done & (1 << mirror)) - finished = 1; - } - } - } - - /* handle the write part of a rebuild composite */ - else if (request->flags & ATA_R_WRITE) { - if (composite->rd_done & (1 << mirror)) { - if (request->result) { - printf("DOH! rebuild failed\n"); /* XXX SOS */ - rdp->rebuild_lba = blk; - } - if (!composite->residual) - finished = 1; - } - } - mtx_unlock(&composite->lock); - } - - /* if read failed retry on the mirror */ - else if (request->result) { - request->dev = rdp->disks[mirror].dev; - request->flags &= ~ATA_R_TIMEOUT; - ata_raid_send_request(request); - return; - } - - /* we have good data */ - else { - bp->bio_resid -= request->donecount; - if (!bp->bio_resid) - finished = 1; - } - } - else if (bp->bio_cmd == BIO_WRITE) { - /* do we have a mirror or rebuild to deal with ? */ - if ((composite = request->composite)) { - mtx_lock(&composite->lock); - if (composite->wr_done & (1 << mirror)) { - if (request->result) { - if (composite->request[mirror]->result) { - printf("DOH! all disks failed and got here\n"); - bp->bio_error = EIO; - } - if (rdp->status & AR_S_REBUILDING) { - rdp->rebuild_lba = blk; - printf("DOH! rebuild failed\n"); /* XXX SOS */ - } - bp->bio_resid -= - composite->request[mirror]->donecount; - composite->residual -= - composite->request[mirror]->donecount; - } - else { - bp->bio_resid -= request->donecount; - composite->residual -= request->donecount; - } - if (!composite->residual) - finished = 1; - } - mtx_unlock(&composite->lock); - } - /* no mirror we are done */ - else { - bp->bio_resid -= request->donecount; - if (!bp->bio_resid) - finished = 1; - } - } - } - else - biofinish(bp, NULL, request->result); - break; - - case AR_T_RAID5: - if (request->result) { - rdp->disks[request->this].flags &= ~AR_DF_ONLINE; - ata_raid_config_changed(rdp, 1); - if (rdp->status & AR_S_READY) { - if (bp->bio_cmd == BIO_READ) { - /* do the XOR game to recover data */ - } - if (bp->bio_cmd == BIO_WRITE) { - /* if the parity failed we're OK sortof */ - /* otherwise wee need to do the XOR long dance */ - } - finished = 1; - } - else - biofinish(bp, NULL, request->result); - } - else { - // did we have an XOR game going ?? - bp->bio_resid -= request->donecount; - if (!bp->bio_resid) - finished = 1; - } - break; - - default: - printf("ar%d: unknown array type in ata_raid_done\n", rdp->lun); - } - - if (finished) { - if ((rdp->status & AR_S_REBUILDING) && - rdp->rebuild_lba >= rdp->total_sectors) { - int disk; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if ((rdp->disks[disk].flags & - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) == - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) { - rdp->disks[disk].flags &= ~AR_DF_SPARE; - rdp->disks[disk].flags |= AR_DF_ONLINE; - } - } - rdp->status &= ~AR_S_REBUILDING; - ata_raid_config_changed(rdp, 1); - } - if (!bp->bio_resid) - biodone(bp); - } - - if (composite) { - if (finished) { - /* we are done with this composite, free all resources */ - for (i = 0; i < 32; i++) { - if (composite->rd_needed & (1 << i) || - composite->wr_needed & (1 << i)) { - ata_free_request(composite->request[i]); - } - } - mtx_destroy(&composite->lock); - ata_free_composite(composite); - } - } - else - ata_free_request(request); -} - -static int -ata_raid_dump(void *arg, void *virtual, vm_offset_t physical, - off_t offset, size_t length) -{ - struct disk *dp = arg; - struct ar_softc *rdp = dp->d_drv1; - struct bio bp; - - /* length zero is special and really means flush buffers to media */ - if (!length) { - int disk, error; - - for (disk = 0, error = 0; disk < rdp->total_disks; disk++) - if (rdp->disks[disk].dev) - error |= ata_controlcmd(rdp->disks[disk].dev, - ATA_FLUSHCACHE, 0, 0, 0); - return (error ? EIO : 0); - } - - bzero(&bp, sizeof(struct bio)); - bp.bio_disk = dp; - bp.bio_pblkno = offset / DEV_BSIZE; - bp.bio_bcount = length; - bp.bio_data = virtual; - bp.bio_cmd = BIO_WRITE; - ata_raid_strategy(&bp); - return bp.bio_error; -} - -static void -ata_raid_config_changed(struct ar_softc *rdp, int writeback) -{ - int disk, count, status; - - mtx_lock(&rdp->lock); - - /* set default all working mode */ - status = rdp->status; - rdp->status &= ~AR_S_DEGRADED; - rdp->status |= AR_S_READY; - - /* make sure all lost drives are accounted for */ - for (disk = 0; disk < rdp->total_disks; disk++) { - if (!(rdp->disks[disk].flags & AR_DF_PRESENT)) - rdp->disks[disk].flags &= ~AR_DF_ONLINE; - } - - /* depending on RAID type figure out our health status */ - switch (rdp->type) { - case AR_T_JBOD: - case AR_T_SPAN: - case AR_T_RAID0: - for (disk = 0; disk < rdp->total_disks; disk++) - if (!(rdp->disks[disk].flags & AR_DF_ONLINE)) - rdp->status &= ~AR_S_READY; - break; - - case AR_T_RAID1: - case AR_T_RAID01: - for (disk = 0; disk < rdp->width; disk++) { - if (!(rdp->disks[disk].flags & AR_DF_ONLINE) && - !(rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) { - rdp->status &= ~AR_S_READY; - } - else if (((rdp->disks[disk].flags & AR_DF_ONLINE) && - !(rdp->disks[disk + rdp->width].flags & AR_DF_ONLINE)) || - (!(rdp->disks[disk].flags & AR_DF_ONLINE) && - (rdp->disks [disk + rdp->width].flags & AR_DF_ONLINE))) { - rdp->status |= AR_S_DEGRADED; - } - } - break; - - case AR_T_RAID5: - for (count = 0, disk = 0; disk < rdp->total_disks; disk++) { - if (!(rdp->disks[disk].flags & AR_DF_ONLINE)) - count++; - } - if (count) { - if (count > 1) - rdp->status &= ~AR_S_READY; - else - rdp->status |= AR_S_DEGRADED; - } - break; - default: - rdp->status &= ~AR_S_READY; - } - - if (rdp->status != status) { - - /* raid status has changed, update metadata */ - writeback = 1; - - /* announce we have trouble ahead */ - if (!(rdp->status & AR_S_READY)) { - printf("ar%d: FAILURE - %s array broken\n", - rdp->lun, ata_raid_type(rdp)); - } - else if (rdp->status & AR_S_DEGRADED) { - if (rdp->type & (AR_T_RAID1 | AR_T_RAID01)) - printf("ar%d: WARNING - mirror", rdp->lun); - else - printf("ar%d: WARNING - parity", rdp->lun); - printf(" protection lost. %s array in DEGRADED mode\n", - ata_raid_type(rdp)); - } - } - mtx_unlock(&rdp->lock); - if (writeback) - ata_raid_write_metadata(rdp); - -} - -static int -ata_raid_status(struct ata_ioc_raid_status *status) -{ - struct ar_softc *rdp; - int i; - - if (!(rdp = ata_raid_arrays[status->lun])) - return ENXIO; - - status->type = rdp->type; - status->total_disks = rdp->total_disks; - for (i = 0; i < rdp->total_disks; i++ ) { - status->disks[i].state = 0; - if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].dev) { - status->disks[i].lun = device_get_unit(rdp->disks[i].dev); - if (rdp->disks[i].flags & AR_DF_PRESENT) - status->disks[i].state |= AR_DISK_PRESENT; - if (rdp->disks[i].flags & AR_DF_ONLINE) - status->disks[i].state |= AR_DISK_ONLINE; - if (rdp->disks[i].flags & AR_DF_SPARE) - status->disks[i].state |= AR_DISK_SPARE; - } else - status->disks[i].lun = -1; - } - status->interleave = rdp->interleave; - status->status = rdp->status; - status->progress = 100 * rdp->rebuild_lba / rdp->total_sectors; - return 0; -} - -static int -ata_raid_create(struct ata_ioc_raid_config *config) -{ - struct ar_softc *rdp; - device_t subdisk; - int array, disk; - int ctlr = 0, disk_size = 0, total_disks = 0; - - for (array = 0; array < MAX_ARRAYS; array++) { - if (!ata_raid_arrays[array]) - break; - } - if (array >= MAX_ARRAYS) - return ENOSPC; - - if (!(rdp = (struct ar_softc*)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO))) { - printf("ar%d: no memory for metadata storage\n", array); - return ENOMEM; - } - - for (disk = 0; disk < config->total_disks; disk++) { - if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - config->disks[disk]))) { - struct ata_raid_subdisk *ars = device_get_softc(subdisk); - - /* is device already assigned to another array ? */ - if (ars->raid[rdp->volume]) { - config->disks[disk] = -1; - free(rdp, M_AR); - return EBUSY; - } - rdp->disks[disk].dev = device_get_parent(subdisk); - - switch (pci_get_vendor(GRANDPARENT(rdp->disks[disk].dev))) { - case ATA_HIGHPOINT_ID: - /* - * we need some way to decide if it should be v2 or v3 - * for now just use v2 since the v3 BIOS knows how to - * handle that as well. - */ - ctlr = AR_F_HPTV2_RAID; - rdp->disks[disk].sectors = HPTV3_LBA(rdp->disks[disk].dev); - break; - - case ATA_INTEL_ID: - ctlr = AR_F_INTEL_RAID; - rdp->disks[disk].sectors = INTEL_LBA(rdp->disks[disk].dev); - break; - - case ATA_ITE_ID: - ctlr = AR_F_ITE_RAID; - rdp->disks[disk].sectors = ITE_LBA(rdp->disks[disk].dev); - break; - - case ATA_JMICRON_ID: - ctlr = AR_F_JMICRON_RAID; - rdp->disks[disk].sectors = JMICRON_LBA(rdp->disks[disk].dev); - break; - - case 0: /* XXX SOS cover up for bug in our PCI code */ - case ATA_PROMISE_ID: - ctlr = AR_F_PROMISE_RAID; - rdp->disks[disk].sectors = PROMISE_LBA(rdp->disks[disk].dev); - break; - - case ATA_SIS_ID: - ctlr = AR_F_SIS_RAID; - rdp->disks[disk].sectors = SIS_LBA(rdp->disks[disk].dev); - break; - - case ATA_ATI_ID: - case ATA_VIA_ID: - ctlr = AR_F_VIA_RAID; - rdp->disks[disk].sectors = VIA_LBA(rdp->disks[disk].dev); - break; - - default: - /* XXX SOS - * right, so here we are, we have an ATA chip and we want - * to create a RAID and store the metadata. - * we need to find a way to tell what kind of metadata this - * hardware's BIOS might be using (good ideas are welcomed) - * for now we just use our own native FreeBSD format. - * the only way to get support for the BIOS format is to - * setup the RAID from there, in that case we pickup the - * metadata format from the disks (if we support it). - */ - printf("WARNING!! - not able to determine metadata format\n" - "WARNING!! - Using FreeBSD PseudoRAID metadata\n" - "If that is not what you want, use the BIOS to " - "create the array\n"); - ctlr = AR_F_FREEBSD_RAID; - rdp->disks[disk].sectors = PROMISE_LBA(rdp->disks[disk].dev); - break; - } - - /* we need all disks to be of the same format */ - if ((rdp->format & AR_F_FORMAT_MASK) && - (rdp->format & AR_F_FORMAT_MASK) != (ctlr & AR_F_FORMAT_MASK)) { - free(rdp, M_AR); - return EXDEV; - } - else - rdp->format = ctlr; - - /* use the smallest disk of the lots size */ - /* gigabyte boundry ??? XXX SOS */ - if (disk_size) - disk_size = min(rdp->disks[disk].sectors, disk_size); - else - disk_size = rdp->disks[disk].sectors; - rdp->disks[disk].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); - - total_disks++; - } - else { - config->disks[disk] = -1; - free(rdp, M_AR); - return ENXIO; - } - } - - if (total_disks != config->total_disks) { - free(rdp, M_AR); - return ENODEV; - } - - switch (config->type) { - case AR_T_JBOD: - case AR_T_SPAN: - case AR_T_RAID0: - break; - - case AR_T_RAID1: - if (total_disks != 2) { - free(rdp, M_AR); - return EPERM; - } - break; - - case AR_T_RAID01: - if (total_disks % 2 != 0) { - free(rdp, M_AR); - return EPERM; - } - break; - - case AR_T_RAID5: - if (total_disks < 3) { - free(rdp, M_AR); - return EPERM; - } - break; - - default: - free(rdp, M_AR); - return EOPNOTSUPP; - } - 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 (config->interleave >>= 1) - bit++; - rdp->interleave = 1 << bit; - } - rdp->offset_sectors = 0; - - /* values that depend on metadata format */ - switch (rdp->format) { - case AR_F_ADAPTEC_RAID: - rdp->interleave = min(max(32, rdp->interleave), 128); /*+*/ - break; - - case AR_F_HPTV2_RAID: - rdp->interleave = min(max(8, rdp->interleave), 128); /*+*/ - rdp->offset_sectors = HPTV2_LBA(x) + 1; - break; - - case AR_F_HPTV3_RAID: - rdp->interleave = min(max(32, rdp->interleave), 4096); /*+*/ - break; - - case AR_F_INTEL_RAID: - rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/ - break; - - case AR_F_ITE_RAID: - rdp->interleave = min(max(2, rdp->interleave), 128); /*+*/ - break; - - case AR_F_JMICRON_RAID: - rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/ - break; - - case AR_F_LSIV2_RAID: - rdp->interleave = min(max(2, rdp->interleave), 4096); - break; - - case AR_F_LSIV3_RAID: - rdp->interleave = min(max(2, rdp->interleave), 256); - break; - - case AR_F_PROMISE_RAID: - rdp->interleave = min(max(2, rdp->interleave), 2048); /*+*/ - break; - - case AR_F_SII_RAID: - rdp->interleave = min(max(8, rdp->interleave), 256); /*+*/ - break; - - case AR_F_SIS_RAID: - rdp->interleave = min(max(32, rdp->interleave), 512); /*+*/ - break; - - case AR_F_VIA_RAID: - rdp->interleave = min(max(8, rdp->interleave), 128); /*+*/ - break; - } - - rdp->total_disks = total_disks; - rdp->width = total_disks / (rdp->type & (AR_RAID1 | AR_T_RAID01) ? 2 : 1); - rdp->total_sectors = disk_size * (rdp->width - (rdp->type == AR_RAID5)); - rdp->heads = 255; - rdp->sectors = 63; - rdp->cylinders = rdp->total_sectors / (255 * 63); - rdp->rebuild_lba = 0; - rdp->status |= AR_S_READY; - - /* we are committed to this array, grap the subdisks */ - for (disk = 0; disk < config->total_disks; disk++) { - if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - config->disks[disk]))) { - struct ata_raid_subdisk *ars = device_get_softc(subdisk); - - ars->raid[rdp->volume] = rdp; - ars->disk_number[rdp->volume] = disk; - } - } - ata_raid_attach(rdp, 1); - ata_raid_arrays[array] = rdp; - config->lun = array; - return 0; -} - -static int -ata_raid_delete(int array) -{ - struct ar_softc *rdp; - device_t subdisk; - int disk; - - if (!(rdp = ata_raid_arrays[array])) - return ENXIO; - - rdp->status &= ~AR_S_READY; - if (rdp->disk) - disk_destroy(rdp->disk); - - for (disk = 0; disk < rdp->total_disks; disk++) { - if ((rdp->disks[disk].flags & AR_DF_PRESENT) && rdp->disks[disk].dev) { - if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - device_get_unit(rdp->disks[disk].dev)))) { - struct ata_raid_subdisk *ars = device_get_softc(subdisk); - - if (ars->raid[rdp->volume] != rdp) /* XXX SOS */ - device_printf(subdisk, "DOH! this disk doesn't belong\n"); - if (ars->disk_number[rdp->volume] != disk) /* XXX SOS */ - device_printf(subdisk, "DOH! this disk number is wrong\n"); - ars->raid[rdp->volume] = NULL; - ars->disk_number[rdp->volume] = -1; - } - rdp->disks[disk].flags = 0; - } - } - ata_raid_wipe_metadata(rdp); - ata_raid_arrays[array] = NULL; - free(rdp, M_AR); - return 0; -} - -static int -ata_raid_addspare(struct ata_ioc_raid_config *config) -{ - struct ar_softc *rdp; - device_t subdisk; - int disk; - - if (!(rdp = ata_raid_arrays[config->lun])) - return ENXIO; - if (!(rdp->status & AR_S_DEGRADED) || !(rdp->status & AR_S_READY)) - return ENXIO; - if (rdp->status & AR_S_REBUILDING) - return EBUSY; - switch (rdp->type) { - case AR_T_RAID1: - case AR_T_RAID01: - case AR_T_RAID5: - for (disk = 0; disk < rdp->total_disks; disk++ ) { - - if (((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) == - (AR_DF_PRESENT | AR_DF_ONLINE)) && rdp->disks[disk].dev) - continue; - - if ((subdisk = devclass_get_device(ata_raid_sub_devclass, - config->disks[0] ))) { - struct ata_raid_subdisk *ars = device_get_softc(subdisk); - - if (ars->raid[rdp->volume]) - return EBUSY; - - /* XXX SOS validate size etc etc */ - ars->raid[rdp->volume] = rdp; - ars->disk_number[rdp->volume] = disk; - rdp->disks[disk].dev = device_get_parent(subdisk); - rdp->disks[disk].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE); - - device_printf(rdp->disks[disk].dev, - "inserted into ar%d disk%d as spare\n", - rdp->lun, disk); - ata_raid_config_changed(rdp, 1); - return 0; - } - } - return ENXIO; - - default: - return EPERM; - } -} - -static int -ata_raid_rebuild(int array) -{ - struct ar_softc *rdp; - int disk, count; - - if (!(rdp = ata_raid_arrays[array])) - return ENXIO; - /* XXX SOS we should lock the rdp softc here */ - if (!(rdp->status & AR_S_DEGRADED) || !(rdp->status & AR_S_READY)) - return ENXIO; - if (rdp->status & AR_S_REBUILDING) - return EBUSY; - - switch (rdp->type) { - case AR_T_RAID1: - case AR_T_RAID01: - case AR_T_RAID5: - for (count = 0, disk = 0; disk < rdp->total_disks; disk++ ) { - if (((rdp->disks[disk].flags & - (AR_DF_PRESENT|AR_DF_ASSIGNED|AR_DF_ONLINE|AR_DF_SPARE)) == - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_SPARE)) && - rdp->disks[disk].dev) { - count++; - } - } - - if (count) { - rdp->rebuild_lba = 0; - rdp->status |= AR_S_REBUILDING; - return 0; - } - return EIO; - - default: - return EPERM; - } -} - -static int -ata_raid_read_metadata(device_t subdisk) -{ - devclass_t pci_devclass = devclass_find("pci"); - devclass_t atapci_devclass = devclass_find("atapci"); - devclass_t devclass=device_get_devclass(GRANDPARENT(GRANDPARENT(subdisk))); - - /* prioritize vendor native metadata layout if possible */ - if (devclass == pci_devclass || devclass == atapci_devclass) { - switch (pci_get_vendor(GRANDPARENT(device_get_parent(subdisk)))) { - case ATA_HIGHPOINT_ID: - if (ata_raid_hptv3_read_meta(subdisk, ata_raid_arrays)) - return 0; - if (ata_raid_hptv2_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_INTEL_ID: - if (ata_raid_intel_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_ITE_ID: - if (ata_raid_ite_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_JMICRON_ID: - if (ata_raid_jmicron_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_NVIDIA_ID: - if (ata_raid_nvidia_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case 0: /* XXX SOS cover up for bug in our PCI code */ - case ATA_PROMISE_ID: - if (ata_raid_promise_read_meta(subdisk, ata_raid_arrays, 0)) - return 0; - break; - - case ATA_ATI_ID: - case ATA_SILICON_IMAGE_ID: - if (ata_raid_sii_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_SIS_ID: - if (ata_raid_sis_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - - case ATA_VIA_ID: - if (ata_raid_via_read_meta(subdisk, ata_raid_arrays)) - return 0; - break; - } - } - - /* handle controllers that have multiple layout possibilities */ - /* NOTE: the order of these are not insignificant */ - - /* Adaptec HostRAID */ - if (ata_raid_adaptec_read_meta(subdisk, ata_raid_arrays)) - return 0; - - /* LSILogic v3 and v2 */ - if (ata_raid_lsiv3_read_meta(subdisk, ata_raid_arrays)) - return 0; - if (ata_raid_lsiv2_read_meta(subdisk, ata_raid_arrays)) - return 0; - - /* DDF (used by Adaptec, maybe others) */ - if (ata_raid_ddf_read_meta(subdisk, ata_raid_arrays)) - return 0; - - /* if none of the above matched, try FreeBSD native format */ - return ata_raid_promise_read_meta(subdisk, ata_raid_arrays, 1); -} - -static int -ata_raid_write_metadata(struct ar_softc *rdp) -{ - switch (rdp->format) { - case AR_F_FREEBSD_RAID: - case AR_F_PROMISE_RAID: - return ata_raid_promise_write_meta(rdp); - - case AR_F_HPTV3_RAID: - case AR_F_HPTV2_RAID: - /* - * always write HPT v2 metadata, the v3 BIOS knows it as well. - * this is handy since we cannot know what version BIOS is on there - */ - return ata_raid_hptv2_write_meta(rdp); - - case AR_F_INTEL_RAID: - return ata_raid_intel_write_meta(rdp); - - case AR_F_JMICRON_RAID: - return ata_raid_jmicron_write_meta(rdp); - - case AR_F_SIS_RAID: - return ata_raid_sis_write_meta(rdp); - - case AR_F_VIA_RAID: - return ata_raid_via_write_meta(rdp); -#if 0 - case AR_F_HPTV3_RAID: - return ata_raid_hptv3_write_meta(rdp); - - case AR_F_ADAPTEC_RAID: - return ata_raid_adaptec_write_meta(rdp); - - case AR_F_ITE_RAID: - return ata_raid_ite_write_meta(rdp); - - case AR_F_LSIV2_RAID: - return ata_raid_lsiv2_write_meta(rdp); - - case AR_F_LSIV3_RAID: - return ata_raid_lsiv3_write_meta(rdp); - - case AR_F_NVIDIA_RAID: - return ata_raid_nvidia_write_meta(rdp); - - case AR_F_SII_RAID: - return ata_raid_sii_write_meta(rdp); - -#endif - default: - printf("ar%d: writing of %s metadata is NOT supported yet\n", - rdp->lun, ata_raid_format(rdp)); - } - return -1; -} - -static int -ata_raid_wipe_metadata(struct ar_softc *rdp) -{ - int disk, error = 0; - u_int64_t lba; - u_int32_t size; - u_int8_t *meta; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - switch (rdp->format) { - case AR_F_ADAPTEC_RAID: - lba = ADP_LBA(rdp->disks[disk].dev); - size = sizeof(struct adaptec_raid_conf); - break; - - case AR_F_HPTV2_RAID: - lba = HPTV2_LBA(rdp->disks[disk].dev); - size = sizeof(struct hptv2_raid_conf); - break; - - case AR_F_HPTV3_RAID: - lba = HPTV3_LBA(rdp->disks[disk].dev); - size = sizeof(struct hptv3_raid_conf); - break; - - case AR_F_INTEL_RAID: - lba = INTEL_LBA(rdp->disks[disk].dev); - size = 3 * 512; /* XXX SOS */ - break; - - case AR_F_ITE_RAID: - lba = ITE_LBA(rdp->disks[disk].dev); - size = sizeof(struct ite_raid_conf); - break; - - case AR_F_JMICRON_RAID: - lba = JMICRON_LBA(rdp->disks[disk].dev); - size = sizeof(struct jmicron_raid_conf); - break; - - case AR_F_LSIV2_RAID: - lba = LSIV2_LBA(rdp->disks[disk].dev); - size = sizeof(struct lsiv2_raid_conf); - break; - - case AR_F_LSIV3_RAID: - lba = LSIV3_LBA(rdp->disks[disk].dev); - size = sizeof(struct lsiv3_raid_conf); - break; - - case AR_F_NVIDIA_RAID: - lba = NVIDIA_LBA(rdp->disks[disk].dev); - size = sizeof(struct nvidia_raid_conf); - break; - - case AR_F_FREEBSD_RAID: - case AR_F_PROMISE_RAID: - lba = PROMISE_LBA(rdp->disks[disk].dev); - size = sizeof(struct promise_raid_conf); - break; - - case AR_F_SII_RAID: - lba = SII_LBA(rdp->disks[disk].dev); - size = sizeof(struct sii_raid_conf); - break; - - case AR_F_SIS_RAID: - lba = SIS_LBA(rdp->disks[disk].dev); - size = sizeof(struct sis_raid_conf); - break; - - case AR_F_VIA_RAID: - lba = VIA_LBA(rdp->disks[disk].dev); - size = sizeof(struct via_raid_conf); - break; - - default: - printf("ar%d: wiping of %s metadata is NOT supported yet\n", - rdp->lun, ata_raid_format(rdp)); - return ENXIO; - } - if (!(meta = malloc(size, M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - if (ata_raid_rw(rdp->disks[disk].dev, lba, meta, size, - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "wipe metadata failed\n"); - error = EIO; - } - free(meta, M_AR); - } - } - return error; -} - -/* Adaptec HostRAID Metadata */ -static int -ata_raid_adaptec_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct adaptec_raid_conf *meta; - struct ar_softc *raid; - int array, disk, retval = 0; - - if (!(meta = (struct adaptec_raid_conf *) - malloc(sizeof(struct adaptec_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, ADP_LBA(parent), - meta, sizeof(struct adaptec_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "Adaptec read metadata failed\n"); - goto adaptec_out; - } - - /* check if this is a Adaptec RAID struct */ - if (meta->magic_0 != ADP_MAGIC_0 || meta->magic_3 != ADP_MAGIC_3) { - if (testing || bootverbose) - device_printf(parent, "Adaptec check1 failed\n"); - goto adaptec_out; - } - - if (testing || bootverbose) - ata_raid_adaptec_print_meta(meta); - - /* now convert Adaptec metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto adaptec_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_ADAPTEC_RAID)) - continue; - - if (raid->magic_0 && raid->magic_0 != meta->configs[0].magic_0) - continue; - - if (!meta->generation || be32toh(meta->generation) > raid->generation) { - switch (meta->configs[0].type) { - case ADP_T_RAID0: - raid->magic_0 = meta->configs[0].magic_0; - raid->type = AR_T_RAID0; - raid->interleave = 1 << (meta->configs[0].stripe_shift >> 1); - raid->width = be16toh(meta->configs[0].total_disks); - break; - - case ADP_T_RAID1: - raid->magic_0 = meta->configs[0].magic_0; - raid->type = AR_T_RAID1; - raid->width = be16toh(meta->configs[0].total_disks) / 2; - break; - - default: - device_printf(parent, "Adaptec unknown RAID type 0x%02x\n", - meta->configs[0].type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto adaptec_out; - } - - raid->format = AR_F_ADAPTEC_RAID; - raid->generation = be32toh(meta->generation); - raid->total_disks = be16toh(meta->configs[0].total_disks); - raid->total_sectors = be32toh(meta->configs[0].sectors); - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - strncpy(raid->name, meta->configs[0].name, - min(sizeof(raid->name), sizeof(meta->configs[0].name))); - - /* clear out any old info */ - if (raid->generation) { - for (disk = 0; disk < raid->total_disks; disk++) { - raid->disks[disk].dev = NULL; - raid->disks[disk].flags = 0; - } - } - } - if (be32toh(meta->generation) >= raid->generation) { - struct ata_device *atadev = device_get_softc(parent); - struct ata_channel *ch = device_get_softc(GRANDPARENT(dev)); - int disk_number = - (ch->unit << !(ch->flags & ATA_NO_SLAVE)) + atadev->unit; - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].sectors = - be32toh(meta->configs[disk_number + 1].sectors); - raid->disks[disk_number].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - } - break; - } - -adaptec_out: - free(meta, M_AR); - return retval; -} - -static uint64_t -ddfbe64toh(uint64_t val) -{ - return (be64toh(val)); -} - -static uint32_t -ddfbe32toh(uint32_t val) -{ - return (be32toh(val)); -} - -static uint16_t -ddfbe16toh(uint16_t val) -{ - return (be16toh(val)); -} - -static uint64_t -ddfle64toh(uint64_t val) -{ - return (le64toh(val)); -} - -static uint32_t -ddfle32toh(uint32_t val) -{ - return (le32toh(val)); -} - -static uint16_t -ddfle16toh(uint16_t val) -{ - return (le16toh(val)); -} - -static int -ata_raid_ddf_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars; - device_t parent = device_get_parent(dev); - struct ddf_header *hdr; - struct ddf_pd_record *pdr; - struct ddf_pd_entry *pde = NULL; - struct ddf_vd_record *vdr; - struct ddf_pdd_record *pdd; - struct ddf_sa_record *sa = NULL; - struct ddf_vdc_record *vdcr = NULL; - struct ddf_vd_entry *vde = NULL; - struct ar_softc *raid; - uint64_t pri_lba; - uint32_t pd_ref, pd_pos; - uint8_t *meta, *cr; - int hdr_len, vd_state = 0, pd_state = 0; - int i, disk, array, retval = 0; - uintptr_t max_cr_addr; - uint64_t (*ddf64toh)(uint64_t) = NULL; - uint32_t (*ddf32toh)(uint32_t) = NULL; - uint16_t (*ddf16toh)(uint16_t) = NULL; - - ars = device_get_softc(dev); - raid = NULL; - - /* Read in the anchor header */ - if (!(meta = malloc(DDF_HEADER_LENGTH, M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, DDF_LBA(parent), - meta, DDF_HEADER_LENGTH, ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "DDF read metadata failed\n"); - goto ddf_out; - } - - /* - * Check if this is a DDF RAID struct. Note the apparent "flexibility" - * regarding endianness. - */ - hdr = (struct ddf_header *)meta; - if (be32toh(hdr->Signature) == DDF_HEADER_SIGNATURE) { - ddf64toh = ddfbe64toh; - ddf32toh = ddfbe32toh; - ddf16toh = ddfbe16toh; - } else if (le32toh(hdr->Signature) == DDF_HEADER_SIGNATURE) { - ddf64toh = ddfle64toh; - ddf32toh = ddfle32toh; - ddf16toh = ddfle16toh; - } else - goto ddf_out; - - if (hdr->Header_Type != DDF_HEADER_ANCHOR) { - if (testing || bootverbose) - device_printf(parent, "DDF check1 failed\n"); - goto ddf_out; - } - - pri_lba = ddf64toh(hdr->Primary_Header_LBA); - hdr_len = ddf32toh(hdr->cd_section) + ddf32toh(hdr->cd_length); - hdr_len = max(hdr_len,ddf32toh(hdr->pdr_section)+ddf32toh(hdr->pdr_length)); - hdr_len = max(hdr_len,ddf32toh(hdr->vdr_section)+ddf32toh(hdr->vdr_length)); - hdr_len = max(hdr_len,ddf32toh(hdr->cr_section) +ddf32toh(hdr->cr_length)); - hdr_len = max(hdr_len,ddf32toh(hdr->pdd_section)+ddf32toh(hdr->pdd_length)); - if (testing || bootverbose) - device_printf(parent, "DDF pri_lba= %llu length= %d blocks\n", - (unsigned long long)pri_lba, hdr_len); - if ((pri_lba + hdr_len) > DDF_LBA(parent)) { - device_printf(parent, "DDF exceeds length of disk\n"); - goto ddf_out; - } - - /* Don't need the anchor anymore, read the rest of the metadata */ - free(meta, M_AR); - if (!(meta = malloc(hdr_len * DEV_BSIZE, M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, pri_lba, meta, hdr_len * DEV_BSIZE, ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "DDF read full metadata failed\n"); - goto ddf_out; - } - - /* Check that we got a Primary Header */ - hdr = (struct ddf_header *)meta; - if ((ddf32toh(hdr->Signature) != DDF_HEADER_SIGNATURE) || - (hdr->Header_Type != DDF_HEADER_PRIMARY)) { - if (testing || bootverbose) - device_printf(parent, "DDF check2 failed\n"); - goto ddf_out; - } - - if (testing || bootverbose) - ata_raid_ddf_print_meta(meta); - - if ((hdr->Open_Flag >= 0x01) && (hdr->Open_Flag <= 0x0f)) { - device_printf(parent, "DDF Header open, possibly corrupt metadata\n"); - goto ddf_out; - } - - pdr = (struct ddf_pd_record*)(meta + ddf32toh(hdr->pdr_section)*DEV_BSIZE); - vdr = (struct ddf_vd_record*)(meta + ddf32toh(hdr->vdr_section)*DEV_BSIZE); - cr = (uint8_t *)(meta + ddf32toh(hdr->cr_section)*DEV_BSIZE); - pdd = (struct ddf_pdd_record*)(meta + ddf32toh(hdr->pdd_section)*DEV_BSIZE); - - /* Verify the Physical Disk Device Record */ - if (ddf32toh(pdd->Signature) != DDF_PDD_SIGNATURE) { - device_printf(parent, "Invalid PD Signature\n"); - goto ddf_out; - } - pd_ref = ddf32toh(pdd->PD_Reference); - pd_pos = -1; - - /* Verify the Physical Disk Record and make sure the disk is usable */ - if (ddf32toh(pdr->Signature) != DDF_PDR_SIGNATURE) { - device_printf(parent, "Invalid PDR Signature\n"); - goto ddf_out; - } - for (i = 0; i < ddf16toh(pdr->Populated_PDEs); i++) { - if (ddf32toh(pdr->entry[i].PD_Reference) != pd_ref) - continue; - pde = &pdr->entry[i]; - pd_state = ddf16toh(pde->PD_State); - } - if ((pde == NULL) || - ((pd_state & DDF_PDE_ONLINE) == 0) || - (pd_state & (DDF_PDE_FAILED|DDF_PDE_MISSING|DDF_PDE_UNRECOVERED))) { - device_printf(parent, "Physical disk not usable\n"); - goto ddf_out; - } - - /* Parse out the configuration record, look for spare and VD records. - * While DDF supports a disk being part of more than one array, and - * thus having more than one VDCR record, that feature is not supported - * by ATA-RAID. Therefore, the first record found takes precedence. - */ - max_cr_addr = (uintptr_t)cr + ddf32toh(hdr->cr_length) * DEV_BSIZE - 1; - for ( ; (uintptr_t)cr < max_cr_addr; - cr += ddf16toh(hdr->Configuration_Record_Length) * DEV_BSIZE) { - switch (ddf32toh(((uint32_t *)cr)[0])) { - case DDF_VDCR_SIGNATURE: - vdcr = (struct ddf_vdc_record *)cr; - goto cr_found; - break; - case DDF_VUCR_SIGNATURE: - /* Don't care about this record */ - break; - case DDF_SA_SIGNATURE: - sa = (struct ddf_sa_record *)cr; - goto cr_found; - break; - case DDF_CR_INVALID: - /* A record was deliberately invalidated */ - break; - default: - device_printf(parent, "Invalid CR signature found\n"); - } - } -cr_found: - if ((vdcr == NULL) /* && (sa == NULL) * Spares not supported yet */) { - device_printf(parent, "No usable configuration record found\n"); - goto ddf_out; - } - - if (vdcr != NULL) { - if (vdcr->Secondary_Element_Count != 1) { - device_printf(parent, "Unsupported multi-level Virtual Disk\n"); - goto ddf_out; - } - - /* Find the Virtual Disk Entry for this array */ - if (ddf32toh(vdr->Signature) != DDF_VD_RECORD_SIGNATURE) { - device_printf(parent, "Invalid VDR Signature\n"); - goto ddf_out; - } - for (i = 0; i < ddf16toh(vdr->Populated_VDEs); i++) { - if (bcmp(vdr->entry[i].VD_GUID, vdcr->VD_GUID, 24)) - continue; - vde = &vdr->entry[i]; - vd_state = vde->VD_State & DDF_VDE_STATE_MASK; - } - if ((vde == NULL) || - ((vd_state != DDF_VDE_OPTIMAL) && (vd_state != DDF_VDE_DEGRADED))) { - device_printf(parent, "Unusable Virtual Disk\n"); - goto ddf_out; - } - for (i = 0; i < ddf16toh(hdr->Max_Primary_Element_Entries); i++) { - uint32_t pd_tmp; - - pd_tmp = ddf32toh(vdcr->Physical_Disk_Sequence[i]); - if ((pd_tmp == 0x00000000) || (pd_tmp == 0xffffffff)) - continue; - if (pd_tmp == pd_ref) { - pd_pos = i; - break; - } - } - if (pd_pos == -1) { - device_printf(parent, "Physical device not part of array\n"); - goto ddf_out; - } - } - - /* now convert DDF metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raid = (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raid) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto ddf_out; - } - } else - raid = raidp[array]; - - if (raid->format && (raid->format != AR_F_DDF_RAID)) - continue; - - if (raid->magic_0 && (raid->magic_0 != crc32(vde->VD_GUID, 24))) - continue; - - if (!raidp[array]) { - raidp[array] = raid; - - switch (vdcr->Primary_RAID_Level) { - case DDF_VDCR_RAID0: - raid->magic_0 = crc32(vde->VD_GUID, 24); - raid->magic_1 = ddf16toh(vde->VD_Number); - raid->type = AR_T_RAID0; - raid->interleave = 1 << vdcr->Stripe_Size; - raid->width = ddf16toh(vdcr->Primary_Element_Count); - break; - - case DDF_VDCR_RAID1: - raid->magic_0 = crc32(vde->VD_GUID, 24); - raid->magic_1 = ddf16toh(vde->VD_Number); - raid->type = AR_T_RAID1; - raid->width = 1; - break; - - default: - device_printf(parent, "DDF unsupported RAID type 0x%02x\n", - vdcr->Primary_RAID_Level); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto ddf_out; - } - - raid->format = AR_F_DDF_RAID; - raid->generation = ddf32toh(vdcr->Sequence_Number); - raid->total_disks = ddf16toh(vdcr->Primary_Element_Count); - raid->total_sectors = ddf64toh(vdcr->VD_Size); - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - strncpy(raid->name, vde->VD_Name, - min(sizeof(raid->name), sizeof(vde->VD_Name))); - - /* clear out any old info */ - if (raid->generation) { - for (disk = 0; disk < raid->total_disks; disk++) { - raid->disks[disk].dev = NULL; - raid->disks[disk].flags = 0; - } - } - } - if (ddf32toh(vdcr->Sequence_Number) >= raid->generation) { - int disk_number = pd_pos; - - raid->disks[disk_number].dev = parent; - - /* Adaptec appears to not set vdcr->Block_Count, yet again in - * gross violation of the spec. - */ - raid->disks[disk_number].sectors = ddf64toh(vdcr->Block_Count); - if (raid->disks[disk_number].sectors == 0) - raid->disks[disk_number].sectors=ddf64toh(pde->Configured_Size); - raid->disks[disk_number].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - } - break; - } - -ddf_out: - free(meta, M_AR); - return retval; -} - -/* Highpoint V2 RocketRAID Metadata */ -static int -ata_raid_hptv2_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct hptv2_raid_conf *meta; - struct ar_softc *raid = NULL; - int array, disk_number = 0, retval = 0; - - if (!(meta = (struct hptv2_raid_conf *) - malloc(sizeof(struct hptv2_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, HPTV2_LBA(parent), - meta, sizeof(struct hptv2_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v2) read metadata failed\n"); - goto hptv2_out; - } - - /* check if this is a HighPoint v2 RAID struct */ - if (meta->magic != HPTV2_MAGIC_OK && meta->magic != HPTV2_MAGIC_BAD) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v2) check1 failed\n"); - goto hptv2_out; - } - - /* is this disk defined, or an old leftover/spare ? */ - if (!meta->magic_0) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v2) check2 failed\n"); - goto hptv2_out; - } - - if (testing || bootverbose) - ata_raid_hptv2_print_meta(meta); - - /* now convert HighPoint (v2) metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto hptv2_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_HPTV2_RAID)) - continue; - - switch (meta->type) { - case HPTV2_T_RAID0: - if ((meta->order & (HPTV2_O_RAID0|HPTV2_O_OK)) == - (HPTV2_O_RAID0|HPTV2_O_OK)) - goto highpoint_raid1; - if (meta->order & (HPTV2_O_RAID0 | HPTV2_O_RAID1)) - goto highpoint_raid01; - if (raid->magic_0 && raid->magic_0 != meta->magic_0) - continue; - raid->magic_0 = meta->magic_0; - raid->type = AR_T_RAID0; - raid->interleave = 1 << meta->stripe_shift; - disk_number = meta->disk_number; - if (!(meta->order & HPTV2_O_OK)) - meta->magic = 0; /* mark bad */ - break; - - case HPTV2_T_RAID1: -highpoint_raid1: - if (raid->magic_0 && raid->magic_0 != meta->magic_0) - continue; - raid->magic_0 = meta->magic_0; - raid->type = AR_T_RAID1; - disk_number = (meta->disk_number > 0); - break; - - case HPTV2_T_RAID01_RAID0: -highpoint_raid01: - if (meta->order & HPTV2_O_RAID0) { - if ((raid->magic_0 && raid->magic_0 != meta->magic_0) || - (raid->magic_1 && raid->magic_1 != meta->magic_1)) - continue; - raid->magic_0 = meta->magic_0; - raid->magic_1 = meta->magic_1; - raid->type = AR_T_RAID01; - raid->interleave = 1 << meta->stripe_shift; - disk_number = meta->disk_number; - } - else { - if (raid->magic_1 && raid->magic_1 != meta->magic_1) - continue; - raid->magic_1 = meta->magic_1; - raid->type = AR_T_RAID01; - raid->interleave = 1 << meta->stripe_shift; - disk_number = meta->disk_number + meta->array_width; - if (!(meta->order & HPTV2_O_RAID1)) - meta->magic = 0; /* mark bad */ - } - break; - - case HPTV2_T_SPAN: - if (raid->magic_0 && raid->magic_0 != meta->magic_0) - continue; - raid->magic_0 = meta->magic_0; - raid->type = AR_T_SPAN; - disk_number = meta->disk_number; - break; - - default: - device_printf(parent, "Highpoint (v2) unknown RAID type 0x%02x\n", - meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto hptv2_out; - } - - raid->format |= AR_F_HPTV2_RAID; - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].flags = (AR_DF_PRESENT | AR_DF_ASSIGNED); - raid->lun = array; - strncpy(raid->name, meta->name_1, - min(sizeof(raid->name), sizeof(meta->name_1))); - if (meta->magic == HPTV2_MAGIC_OK) { - raid->disks[disk_number].flags |= AR_DF_ONLINE; - raid->width = meta->array_width; - raid->total_sectors = meta->total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = HPTV2_LBA(parent) + 1; - raid->rebuild_lba = meta->rebuild_lba; - raid->disks[disk_number].sectors = - raid->total_sectors / raid->width; - } - else - raid->disks[disk_number].flags &= ~AR_DF_ONLINE; - - if ((raid->type & AR_T_RAID0) && (raid->total_disks < raid->width)) - raid->total_disks = raid->width; - if (disk_number >= raid->total_disks) - raid->total_disks = disk_number + 1; - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - break; - } - -hptv2_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_hptv2_write_meta(struct ar_softc *rdp) -{ - struct hptv2_raid_conf *meta; - struct timeval timestamp; - int disk, error = 0; - - if (!(meta = (struct hptv2_raid_conf *) - malloc(sizeof(struct hptv2_raid_conf), M_AR, M_NOWAIT | M_ZERO))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - microtime(×tamp); - rdp->magic_0 = timestamp.tv_sec + 2; - rdp->magic_1 = timestamp.tv_sec; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) == - (AR_DF_PRESENT | AR_DF_ONLINE)) - meta->magic = HPTV2_MAGIC_OK; - if (rdp->disks[disk].flags & AR_DF_ASSIGNED) { - meta->magic_0 = rdp->magic_0; - if (strlen(rdp->name)) - strncpy(meta->name_1, rdp->name, sizeof(meta->name_1)); - else - strcpy(meta->name_1, "FreeBSD"); - } - meta->disk_number = disk; - - switch (rdp->type) { - case AR_T_RAID0: - meta->type = HPTV2_T_RAID0; - strcpy(meta->name_2, "RAID 0"); - if (rdp->disks[disk].flags & AR_DF_ONLINE) - meta->order = HPTV2_O_OK; - break; - - case AR_T_RAID1: - meta->type = HPTV2_T_RAID0; - strcpy(meta->name_2, "RAID 1"); - meta->disk_number = (disk < rdp->width) ? disk : disk + 5; - meta->order = HPTV2_O_RAID0 | HPTV2_O_OK; - break; - - case AR_T_RAID01: - meta->type = HPTV2_T_RAID01_RAID0; - strcpy(meta->name_2, "RAID 0+1"); - if (rdp->disks[disk].flags & AR_DF_ONLINE) { - if (disk < rdp->width) { - meta->order = (HPTV2_O_RAID0 | HPTV2_O_RAID1); - meta->magic_0 = rdp->magic_0 - 1; - } - else { - meta->order = HPTV2_O_RAID1; - meta->disk_number -= rdp->width; - } - } - else - meta->magic_0 = rdp->magic_0 - 1; - meta->magic_1 = rdp->magic_1; - break; - - case AR_T_SPAN: - meta->type = HPTV2_T_SPAN; - strcpy(meta->name_2, "SPAN"); - break; - default: - free(meta, M_AR); - return ENODEV; - } - - meta->array_width = rdp->width; - meta->stripe_shift = (rdp->width > 1) ? (ffs(rdp->interleave)-1) : 0; - meta->total_sectors = rdp->total_sectors; - meta->rebuild_lba = rdp->rebuild_lba; - if (testing || bootverbose) - ata_raid_hptv2_print_meta(meta); - if (rdp->disks[disk].dev) { - if (ata_raid_rw(rdp->disks[disk].dev, - HPTV2_LBA(rdp->disks[disk].dev), meta, - sizeof(struct promise_raid_conf), - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - free(meta, M_AR); - return error; -} - -/* Highpoint V3 RocketRAID Metadata */ -static int -ata_raid_hptv3_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct hptv3_raid_conf *meta; - struct ar_softc *raid = NULL; - int array, disk_number, retval = 0; - - if (!(meta = (struct hptv3_raid_conf *) - malloc(sizeof(struct hptv3_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, HPTV3_LBA(parent), - meta, sizeof(struct hptv3_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v3) read metadata failed\n"); - goto hptv3_out; - } - - /* check if this is a HighPoint v3 RAID struct */ - if (meta->magic != HPTV3_MAGIC) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v3) check1 failed\n"); - goto hptv3_out; - } - - /* check if there are any config_entries */ - if (meta->config_entries < 1) { - if (testing || bootverbose) - device_printf(parent, "HighPoint (v3) check2 failed\n"); - goto hptv3_out; - } - - if (testing || bootverbose) - ata_raid_hptv3_print_meta(meta); - - /* now convert HighPoint (v3) metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto hptv3_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_HPTV3_RAID)) - continue; - - if ((raid->format & AR_F_HPTV3_RAID) && raid->magic_0 != meta->magic_0) - continue; - - switch (meta->configs[0].type) { - case HPTV3_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = meta->configs[0].total_disks; - disk_number = meta->configs[0].disk_number; - break; - - case HPTV3_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = meta->configs[0].total_disks / 2; - disk_number = meta->configs[0].disk_number; - break; - - case HPTV3_T_RAID5: - raid->type = AR_T_RAID5; - raid->width = meta->configs[0].total_disks; - disk_number = meta->configs[0].disk_number; - break; - - case HPTV3_T_SPAN: - raid->type = AR_T_SPAN; - raid->width = meta->configs[0].total_disks; - disk_number = meta->configs[0].disk_number; - break; - - default: - device_printf(parent, "Highpoint (v3) unknown RAID type 0x%02x\n", - meta->configs[0].type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto hptv3_out; - } - if (meta->config_entries == 2) { - switch (meta->configs[1].type) { - case HPTV3_T_RAID1: - if (raid->type == AR_T_RAID0) { - raid->type = AR_T_RAID01; - disk_number = meta->configs[1].disk_number + - (meta->configs[0].disk_number << 1); - break; - } - default: - device_printf(parent, "Highpoint (v3) unknown level 2 0x%02x\n", - meta->configs[1].type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto hptv3_out; - } - } - - raid->magic_0 = meta->magic_0; - raid->format = AR_F_HPTV3_RAID; - raid->generation = meta->timestamp; - raid->interleave = 1 << meta->configs[0].stripe_shift; - raid->total_disks = meta->configs[0].total_disks + - meta->configs[1].total_disks; - raid->total_sectors = meta->configs[0].total_sectors + - ((u_int64_t)meta->configs_high[0].total_sectors << 32); - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = meta->configs[0].rebuild_lba + - ((u_int64_t)meta->configs_high[0].rebuild_lba << 32); - raid->lun = array; - strncpy(raid->name, meta->name, - min(sizeof(raid->name), sizeof(meta->name))); - raid->disks[disk_number].sectors = raid->total_sectors / - (raid->type == AR_T_RAID5 ? raid->width - 1 : raid->width); - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - break; - } - -hptv3_out: - free(meta, M_AR); - return retval; -} - -/* Intel MatrixRAID Metadata */ -static int -ata_raid_intel_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct intel_raid_conf *meta; - struct intel_raid_mapping *map; - struct ar_softc *raid = NULL; - u_int32_t checksum, *ptr; - int array, count, disk, volume = 1, retval = 0; - char *tmp; - - if (!(meta = (struct intel_raid_conf *) - malloc(1536, M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, INTEL_LBA(parent), meta, 1024, ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "Intel read metadata failed\n"); - goto intel_out; - } - tmp = (char *)meta; - bcopy(tmp, tmp+1024, 512); - bcopy(tmp+512, tmp, 1024); - bzero(tmp+1024, 512); - - /* check if this is a Intel RAID struct */ - if (strncmp(meta->intel_id, INTEL_MAGIC, strlen(INTEL_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "Intel check1 failed\n"); - goto intel_out; - } - - for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; - count < (meta->config_size / sizeof(u_int32_t)); count++) { - checksum += *ptr++; - } - checksum -= meta->checksum; - if (checksum != meta->checksum) { - if (testing || bootverbose) - device_printf(parent, "Intel check2 failed\n"); - goto intel_out; - } - - if (testing || bootverbose) - ata_raid_intel_print_meta(meta); - - map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks]; - - /* now convert Intel metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto intel_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_INTEL_RAID)) - continue; - - if ((raid->format & AR_F_INTEL_RAID) && - (raid->magic_0 != meta->config_id)) - continue; - - /* - * update our knowledge about the array config based on generation - * NOTE: there can be multiple volumes on a disk set - */ - if (!meta->generation || meta->generation > raid->generation) { - switch (map->type) { - case INTEL_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = map->total_disks; - break; - - case INTEL_T_RAID1: - if (map->total_disks == 4) - raid->type = AR_T_RAID01; - else - raid->type = AR_T_RAID1; - raid->width = map->total_disks / 2; - break; - - case INTEL_T_RAID5: - raid->type = AR_T_RAID5; - raid->width = map->total_disks; - break; - - default: - device_printf(parent, "Intel unknown RAID type 0x%02x\n", - map->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto intel_out; - } - - switch (map->status) { - case INTEL_S_READY: - raid->status = AR_S_READY; - break; - case INTEL_S_DEGRADED: - raid->status |= AR_S_DEGRADED; - break; - case INTEL_S_DISABLED: - case INTEL_S_FAILURE: - raid->status = 0; - } - - raid->magic_0 = meta->config_id; - raid->format = AR_F_INTEL_RAID; - raid->generation = meta->generation; - raid->interleave = map->stripe_sectors; - raid->total_disks = map->total_disks; - raid->total_sectors = map->total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = map->offset; - raid->rebuild_lba = 0; - raid->lun = array; - raid->volume = volume - 1; - strncpy(raid->name, map->name, - min(sizeof(raid->name), sizeof(map->name))); - - /* clear out any old info */ - for (disk = 0; disk < raid->total_disks; disk++) { - u_int disk_idx = map->disk_idx[disk] & 0xffff; - - raid->disks[disk].dev = NULL; - bcopy(meta->disk[disk_idx].serial, - raid->disks[disk].serial, - sizeof(raid->disks[disk].serial)); - raid->disks[disk].sectors = - meta->disk[disk_idx].sectors; - raid->disks[disk].flags = 0; - if (meta->disk[disk_idx].flags & INTEL_F_ONLINE) - raid->disks[disk].flags |= AR_DF_ONLINE; - if (meta->disk[disk_idx].flags & INTEL_F_ASSIGNED) - raid->disks[disk].flags |= AR_DF_ASSIGNED; - if (meta->disk[disk_idx].flags & INTEL_F_SPARE) { - raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED); - raid->disks[disk].flags |= AR_DF_SPARE; - } - if (meta->disk[disk_idx].flags & INTEL_F_DOWN) - raid->disks[disk].flags &= ~AR_DF_ONLINE; - } - } - if (meta->generation >= raid->generation) { - for (disk = 0; disk < raid->total_disks; disk++) { - struct ata_device *atadev = device_get_softc(parent); - int len; - - for (len = 0; len < sizeof(atadev->param.serial); len++) { - if (atadev->param.serial[len] < 0x20) - break; - } - len = (len > sizeof(raid->disks[disk].serial)) ? - len - sizeof(raid->disks[disk].serial) : 0; - if (!strncmp(raid->disks[disk].serial, atadev->param.serial + len, - sizeof(raid->disks[disk].serial))) { - raid->disks[disk].dev = parent; - raid->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_ONLINE); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk; - retval = 1; - } - } - } - else - goto intel_out; - - if (retval) { - if (volume < meta->total_volumes) { - map = (struct intel_raid_mapping *) - &map->disk_idx[map->total_disks]; - volume++; - retval = 0; - continue; - } - break; - } - else { - free(raidp[array], M_AR); - raidp[array] = NULL; - if (volume == 2) - retval = 1; - } - } - -intel_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_intel_write_meta(struct ar_softc *rdp) -{ - struct intel_raid_conf *meta; - struct intel_raid_mapping *map; - struct timeval timestamp; - u_int32_t checksum, *ptr; - int count, disk, error = 0; - char *tmp; - - if (!(meta = (struct intel_raid_conf *) - malloc(1536, M_AR, M_NOWAIT | M_ZERO))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - rdp->generation++; - if (!rdp->magic_0) { - microtime(×tamp); - rdp->magic_0 = timestamp.tv_sec ^ timestamp.tv_usec; - } - - bcopy(INTEL_MAGIC, meta->intel_id, sizeof(meta->intel_id)); - bcopy(INTEL_VERSION_1100, meta->version, sizeof(meta->version)); - meta->config_id = rdp->magic_0; - meta->generation = rdp->generation; - meta->total_disks = rdp->total_disks; - meta->total_volumes = 1; /* XXX SOS */ - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - struct ata_channel *ch = - device_get_softc(device_get_parent(rdp->disks[disk].dev)); - struct ata_device *atadev = - device_get_softc(rdp->disks[disk].dev); - int len; - - for (len = 0; len < sizeof(atadev->param.serial); len++) { - if (atadev->param.serial[len] < 0x20) - break; - } - len = (len > sizeof(rdp->disks[disk].serial)) ? - len - sizeof(rdp->disks[disk].serial) : 0; - bcopy(atadev->param.serial + len, meta->disk[disk].serial, - sizeof(rdp->disks[disk].serial)); - meta->disk[disk].sectors = rdp->disks[disk].sectors; - meta->disk[disk].id = (ch->unit << 16) | atadev->unit; - } - else - meta->disk[disk].sectors = rdp->total_sectors / rdp->width; - meta->disk[disk].flags = 0; - if (rdp->disks[disk].flags & AR_DF_SPARE) - meta->disk[disk].flags |= INTEL_F_SPARE; - else { - if (rdp->disks[disk].flags & AR_DF_ONLINE) - meta->disk[disk].flags |= INTEL_F_ONLINE; - else - meta->disk[disk].flags |= INTEL_F_DOWN; - if (rdp->disks[disk].flags & AR_DF_ASSIGNED) - meta->disk[disk].flags |= INTEL_F_ASSIGNED; - } - } - map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks]; - - bcopy(rdp->name, map->name, sizeof(rdp->name)); - map->total_sectors = rdp->total_sectors; - map->state = 12; /* XXX SOS */ - map->offset = rdp->offset_sectors; - map->stripe_count = rdp->total_sectors / (rdp->interleave*rdp->total_disks); - map->stripe_sectors = rdp->interleave; - map->disk_sectors = rdp->total_sectors / rdp->width; - map->status = INTEL_S_READY; /* XXX SOS */ - switch (rdp->type) { - case AR_T_RAID0: - map->type = INTEL_T_RAID0; - break; - case AR_T_RAID1: - map->type = INTEL_T_RAID1; - break; - case AR_T_RAID01: - map->type = INTEL_T_RAID1; - break; - case AR_T_RAID5: - map->type = INTEL_T_RAID5; - break; - default: - free(meta, M_AR); - return ENODEV; - } - map->total_disks = rdp->total_disks; - map->magic[0] = 0x02; - map->magic[1] = 0xff; - map->magic[2] = 0x01; - for (disk = 0; disk < rdp->total_disks; disk++) - map->disk_idx[disk] = disk; - - meta->config_size = (char *)&map->disk_idx[disk] - (char *)meta; - for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; - count < (meta->config_size / sizeof(u_int32_t)); count++) { - checksum += *ptr++; - } - meta->checksum = checksum; - - if (testing || bootverbose) - ata_raid_intel_print_meta(meta); - - tmp = (char *)meta; - bcopy(tmp, tmp+1024, 512); - bcopy(tmp+512, tmp, 1024); - bzero(tmp+1024, 512); - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - if (ata_raid_rw(rdp->disks[disk].dev, - INTEL_LBA(rdp->disks[disk].dev), - meta, 1024, ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - free(meta, M_AR); - return error; -} - - -/* Integrated Technology Express Metadata */ -static int -ata_raid_ite_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct ite_raid_conf *meta; - struct ar_softc *raid = NULL; - int array, disk_number, count, retval = 0; - u_int16_t *ptr; - - if (!(meta = (struct ite_raid_conf *) - malloc(sizeof(struct ite_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, ITE_LBA(parent), - meta, sizeof(struct ite_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "ITE read metadata failed\n"); - goto ite_out; - } - - /* check if this is a ITE RAID struct */ - for (ptr = (u_int16_t *)meta->ite_id, count = 0; - count < sizeof(meta->ite_id)/sizeof(uint16_t); count++) - ptr[count] = be16toh(ptr[count]); - - if (strncmp(meta->ite_id, ITE_MAGIC, strlen(ITE_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "ITE check1 failed\n"); - goto ite_out; - } - - if (testing || bootverbose) - ata_raid_ite_print_meta(meta); - - /* now convert ITE metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if ((raid = raidp[array])) { - if (raid->format != AR_F_ITE_RAID) - continue; - if (raid->magic_0 != *((u_int64_t *)meta->timestamp_0)) - continue; - } - - /* if we dont have a disks timestamp the RAID is invalidated */ - if (*((u_int64_t *)meta->timestamp_1) == 0) - goto ite_out; - - if (!raid) { - raidp[array] = (struct ar_softc *)malloc(sizeof(struct ar_softc), - M_AR, M_NOWAIT | M_ZERO); - if (!(raid = raidp[array])) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto ite_out; - } - } - - switch (meta->type) { - case ITE_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = meta->array_width; - raid->total_disks = meta->array_width; - disk_number = meta->disk_number; - break; - - case ITE_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = 1; - raid->total_disks = 2; - disk_number = meta->disk_number; - break; - - case ITE_T_RAID01: - raid->type = AR_T_RAID01; - raid->width = meta->array_width; - raid->total_disks = 4; - disk_number = ((meta->disk_number & 0x02) >> 1) | - ((meta->disk_number & 0x01) << 1); - break; - - case ITE_T_SPAN: - raid->type = AR_T_SPAN; - raid->width = 1; - raid->total_disks = meta->array_width; - disk_number = meta->disk_number; - break; - - default: - device_printf(parent, "ITE unknown RAID type 0x%02x\n", meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto ite_out; - } - - raid->magic_0 = *((u_int64_t *)meta->timestamp_0); - raid->format = AR_F_ITE_RAID; - raid->generation = 0; - raid->interleave = meta->stripe_sectors; - raid->total_sectors = meta->total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].sectors = raid->total_sectors / raid->width; - raid->disks[disk_number].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - break; - } -ite_out: - free(meta, M_AR); - return retval; -} - -/* JMicron Technology Corp Metadata */ -static int -ata_raid_jmicron_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct jmicron_raid_conf *meta; - struct ar_softc *raid = NULL; - u_int16_t checksum, *ptr; - u_int64_t disk_size; - int count, array, disk, total_disks, retval = 0; - - if (!(meta = (struct jmicron_raid_conf *) - malloc(sizeof(struct jmicron_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, JMICRON_LBA(parent), - meta, sizeof(struct jmicron_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, - "JMicron read metadata failed\n"); - } - - /* check for JMicron signature */ - if (strncmp(meta->signature, JMICRON_MAGIC, 2)) { - if (testing || bootverbose) - device_printf(parent, "JMicron check1 failed\n"); - goto jmicron_out; - } - - /* calculate checksum and compare for valid */ - for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 64; count++) - checksum += *ptr++; - if (checksum) { - if (testing || bootverbose) - device_printf(parent, "JMicron check2 failed\n"); - goto jmicron_out; - } - - if (testing || bootverbose) - ata_raid_jmicron_print_meta(meta); - - /* now convert JMicron meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { -jmicron_next: - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto jmicron_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_JMICRON_RAID)) - continue; - - for (total_disks = 0, disk = 0; disk < JM_MAX_DISKS; disk++) { - if (meta->disks[disk]) { - if (raid->format == AR_F_JMICRON_RAID) { - if (bcmp(&meta->disks[disk], - raid->disks[disk].serial, sizeof(u_int32_t))) { - array++; - goto jmicron_next; - } - } - else - bcopy(&meta->disks[disk], - raid->disks[disk].serial, sizeof(u_int32_t)); - total_disks++; - } - } - /* handle spares XXX SOS */ - - switch (meta->type) { - case JM_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = total_disks; - break; - - case JM_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = 1; - break; - - case JM_T_RAID01: - raid->type = AR_T_RAID01; - raid->width = total_disks / 2; - break; - - case JM_T_RAID5: - raid->type = AR_T_RAID5; - raid->width = total_disks; - break; - - case JM_T_JBOD: - raid->type = AR_T_SPAN; - raid->width = 1; - break; - - default: - device_printf(parent, - "JMicron unknown RAID type 0x%02x\n", meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto jmicron_out; - } - disk_size = (meta->disk_sectors_high << 16) + meta->disk_sectors_low; - raid->format = AR_F_JMICRON_RAID; - strncpy(raid->name, meta->name, sizeof(meta->name)); - raid->generation = 0; - raid->interleave = 2 << meta->stripe_shift; - raid->total_disks = total_disks; - raid->total_sectors = disk_size * (raid->width-(raid->type==AR_RAID5)); - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = meta->offset * 16; - raid->rebuild_lba = 0; - raid->lun = array; - - for (disk = 0; disk < raid->total_disks; disk++) { - if (meta->disks[disk] == meta->disk_id) { - raid->disks[disk].dev = parent; - raid->disks[disk].sectors = disk_size; - raid->disks[disk].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk; - retval = 1; - break; - } - } - break; - } -jmicron_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_jmicron_write_meta(struct ar_softc *rdp) -{ - struct jmicron_raid_conf *meta; - u_int64_t disk_sectors; - int disk, error = 0; - - if (!(meta = (struct jmicron_raid_conf *) - malloc(sizeof(struct jmicron_raid_conf), M_AR, M_NOWAIT | M_ZERO))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - rdp->generation++; - switch (rdp->type) { - case AR_T_JBOD: - meta->type = JM_T_JBOD; - break; - - case AR_T_RAID0: - meta->type = JM_T_RAID0; - break; - - case AR_T_RAID1: - meta->type = JM_T_RAID1; - break; - - case AR_T_RAID5: - meta->type = JM_T_RAID5; - break; - - case AR_T_RAID01: - meta->type = JM_T_RAID01; - break; - - default: - free(meta, M_AR); - return ENODEV; - } - bcopy(JMICRON_MAGIC, meta->signature, sizeof(JMICRON_MAGIC)); - meta->version = JMICRON_VERSION; - meta->offset = rdp->offset_sectors / 16; - disk_sectors = rdp->total_sectors / (rdp->width - (rdp->type == AR_RAID5)); - meta->disk_sectors_low = disk_sectors & 0xffff; - meta->disk_sectors_high = disk_sectors >> 16; - strncpy(meta->name, rdp->name, sizeof(meta->name)); - meta->stripe_shift = ffs(rdp->interleave) - 2; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].serial[0]) - bcopy(rdp->disks[disk].serial,&meta->disks[disk],sizeof(u_int32_t)); - else - meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev; - } - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - u_int16_t checksum = 0, *ptr; - int count; - - meta->disk_id = meta->disks[disk]; - meta->checksum = 0; - for (ptr = (u_int16_t *)meta, count = 0; count < 64; count++) - checksum += *ptr++; - meta->checksum -= checksum; - - if (testing || bootverbose) - ata_raid_jmicron_print_meta(meta); - - if (ata_raid_rw(rdp->disks[disk].dev, - JMICRON_LBA(rdp->disks[disk].dev), - meta, sizeof(struct jmicron_raid_conf), - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - /* handle spares XXX SOS */ - - free(meta, M_AR); - return error; -} - -/* LSILogic V2 MegaRAID Metadata */ -static int -ata_raid_lsiv2_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct lsiv2_raid_conf *meta; - struct ar_softc *raid = NULL; - int array, retval = 0; - - if (!(meta = (struct lsiv2_raid_conf *) - malloc(sizeof(struct lsiv2_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, LSIV2_LBA(parent), - meta, sizeof(struct lsiv2_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "LSI (v2) read metadata failed\n"); - goto lsiv2_out; - } - - /* check if this is a LSI RAID struct */ - if (strncmp(meta->lsi_id, LSIV2_MAGIC, strlen(LSIV2_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "LSI (v2) check1 failed\n"); - goto lsiv2_out; - } - - if (testing || bootverbose) - ata_raid_lsiv2_print_meta(meta); - - /* now convert LSI (v2) config meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - int raid_entry, conf_entry; - - if (!raidp[array + meta->raid_number]) { - raidp[array + meta->raid_number] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array + meta->raid_number]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto lsiv2_out; - } - } - raid = raidp[array + meta->raid_number]; - if (raid->format && (raid->format != AR_F_LSIV2_RAID)) - continue; - - if (raid->magic_0 && - ((raid->magic_0 != meta->timestamp) || - (raid->magic_1 != meta->raid_number))) - continue; - - array += meta->raid_number; - - raid_entry = meta->raid_number; - conf_entry = (meta->configs[raid_entry].raid.config_offset >> 4) + - meta->disk_number - 1; - - switch (meta->configs[raid_entry].raid.type) { - case LSIV2_T_RAID0: - raid->magic_0 = meta->timestamp; - raid->magic_1 = meta->raid_number; - raid->type = AR_T_RAID0; - raid->interleave = meta->configs[raid_entry].raid.stripe_sectors; - raid->width = meta->configs[raid_entry].raid.array_width; - break; - - case LSIV2_T_RAID1: - raid->magic_0 = meta->timestamp; - raid->magic_1 = meta->raid_number; - raid->type = AR_T_RAID1; - raid->width = meta->configs[raid_entry].raid.array_width; - break; - - case LSIV2_T_RAID0 | LSIV2_T_RAID1: - raid->magic_0 = meta->timestamp; - raid->magic_1 = meta->raid_number; - raid->type = AR_T_RAID01; - raid->interleave = meta->configs[raid_entry].raid.stripe_sectors; - raid->width = meta->configs[raid_entry].raid.array_width; - break; - - default: - device_printf(parent, "LSI v2 unknown RAID type 0x%02x\n", - meta->configs[raid_entry].raid.type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto lsiv2_out; - } - - raid->format = AR_F_LSIV2_RAID; - raid->generation = 0; - raid->total_disks = meta->configs[raid_entry].raid.disk_count; - raid->total_sectors = meta->configs[raid_entry].raid.total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - - if (meta->configs[conf_entry].disk.device != LSIV2_D_NONE) { - raid->disks[meta->disk_number].dev = parent; - raid->disks[meta->disk_number].sectors = - meta->configs[conf_entry].disk.disk_sectors; - raid->disks[meta->disk_number].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = meta->disk_number; - retval = 1; - } - else - raid->disks[meta->disk_number].flags &= ~AR_DF_ONLINE; - - break; - } - -lsiv2_out: - free(meta, M_AR); - return retval; -} - -/* LSILogic V3 MegaRAID Metadata */ -static int -ata_raid_lsiv3_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct lsiv3_raid_conf *meta; - struct ar_softc *raid = NULL; - u_int8_t checksum, *ptr; - int array, entry, count, disk_number, retval = 0; - - if (!(meta = (struct lsiv3_raid_conf *) - malloc(sizeof(struct lsiv3_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, LSIV3_LBA(parent), - meta, sizeof(struct lsiv3_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "LSI (v3) read metadata failed\n"); - goto lsiv3_out; - } - - /* check if this is a LSI RAID struct */ - if (strncmp(meta->lsi_id, LSIV3_MAGIC, strlen(LSIV3_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "LSI (v3) check1 failed\n"); - goto lsiv3_out; - } - - /* check if the checksum is OK */ - for (checksum = 0, ptr = meta->lsi_id, count = 0; count < 512; count++) - checksum += *ptr++; - if (checksum) { - if (testing || bootverbose) - device_printf(parent, "LSI (v3) check2 failed\n"); - goto lsiv3_out; - } - - if (testing || bootverbose) - ata_raid_lsiv3_print_meta(meta); - - /* now convert LSI (v3) config meta into our generic form */ - for (array = 0, entry = 0; array < MAX_ARRAYS && entry < 8;) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto lsiv3_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_LSIV3_RAID)) { - array++; - continue; - } - - if ((raid->format == AR_F_LSIV3_RAID) && - (raid->magic_0 != meta->timestamp)) { - array++; - continue; - } - - switch (meta->raid[entry].total_disks) { - case 0: - entry++; - continue; - case 1: - if (meta->raid[entry].device == meta->device) { - disk_number = 0; - break; - } - if (raid->format) - array++; - entry++; - continue; - case 2: - disk_number = (meta->device & (LSIV3_D_DEVICE|LSIV3_D_CHANNEL))?1:0; - break; - default: - device_printf(parent, "lsiv3 > 2 disk support untested!!\n"); - disk_number = (meta->device & LSIV3_D_DEVICE ? 1 : 0) + - (meta->device & LSIV3_D_CHANNEL ? 2 : 0); - break; - } - - switch (meta->raid[entry].type) { - case LSIV3_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = meta->raid[entry].total_disks; - break; - - case LSIV3_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = meta->raid[entry].array_width; - break; - - default: - device_printf(parent, "LSI v3 unknown RAID type 0x%02x\n", - meta->raid[entry].type); - free(raidp[array], M_AR); - raidp[array] = NULL; - entry++; - continue; - } - - raid->magic_0 = meta->timestamp; - raid->format = AR_F_LSIV3_RAID; - raid->generation = 0; - raid->interleave = meta->raid[entry].stripe_pages * 8; - raid->total_disks = meta->raid[entry].total_disks; - raid->total_sectors = raid->width * meta->raid[entry].sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = meta->raid[entry].offset; - raid->rebuild_lba = 0; - raid->lun = array; - - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].sectors = raid->total_sectors / raid->width; - raid->disks[disk_number].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - entry++; - array++; - } - -lsiv3_out: - free(meta, M_AR); - return retval; -} - -/* nVidia MediaShield Metadata */ -static int -ata_raid_nvidia_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct nvidia_raid_conf *meta; - struct ar_softc *raid = NULL; - u_int32_t checksum, *ptr; - int array, count, retval = 0; - - if (!(meta = (struct nvidia_raid_conf *) - malloc(sizeof(struct nvidia_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, NVIDIA_LBA(parent), - meta, sizeof(struct nvidia_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "nVidia read metadata failed\n"); - goto nvidia_out; - } - - /* check if this is a nVidia RAID struct */ - if (strncmp(meta->nvidia_id, NV_MAGIC, strlen(NV_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "nVidia check1 failed\n"); - goto nvidia_out; - } - - /* check if the checksum is OK */ - for (checksum = 0, ptr = (u_int32_t*)meta, count = 0; - count < meta->config_size; count++) - checksum += *ptr++; - if (checksum) { - if (testing || bootverbose) - device_printf(parent, "nVidia check2 failed\n"); - goto nvidia_out; - } - - if (testing || bootverbose) - ata_raid_nvidia_print_meta(meta); - - /* now convert nVidia meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto nvidia_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_NVIDIA_RAID)) - continue; - - if (raid->format == AR_F_NVIDIA_RAID && - ((raid->magic_0 != meta->magic_1) || - (raid->magic_1 != meta->magic_2))) { - continue; - } - - switch (meta->type) { - case NV_T_SPAN: - raid->type = AR_T_SPAN; - break; - - case NV_T_RAID0: - raid->type = AR_T_RAID0; - break; - - case NV_T_RAID1: - raid->type = AR_T_RAID1; - break; - - case NV_T_RAID5: - raid->type = AR_T_RAID5; - break; - - case NV_T_RAID01: - raid->type = AR_T_RAID01; - break; - - default: - device_printf(parent, "nVidia unknown RAID type 0x%02x\n", - meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto nvidia_out; - } - raid->magic_0 = meta->magic_1; - raid->magic_1 = meta->magic_2; - raid->format = AR_F_NVIDIA_RAID; - raid->generation = 0; - raid->interleave = meta->stripe_sectors; - raid->width = meta->array_width; - raid->total_disks = meta->total_disks; - raid->total_sectors = meta->total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = meta->rebuild_lba; - raid->lun = array; - raid->status = AR_S_READY; - if (meta->status & NV_S_DEGRADED) - raid->status |= AR_S_DEGRADED; - - raid->disks[meta->disk_number].dev = parent; - raid->disks[meta->disk_number].sectors = - raid->total_sectors / raid->width; - raid->disks[meta->disk_number].flags = - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = meta->disk_number; - retval = 1; - break; - } - -nvidia_out: - free(meta, M_AR); - return retval; -} - -/* Promise FastTrak Metadata */ -static int -ata_raid_promise_read_meta(device_t dev, struct ar_softc **raidp, int native) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct promise_raid_conf *meta; - struct ar_softc *raid; - u_int32_t checksum, *ptr; - int array, count, disk, disksum = 0, retval = 0; - - if (!(meta = (struct promise_raid_conf *) - malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, PROMISE_LBA(parent), - meta, sizeof(struct promise_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "%s read metadata failed\n", - native ? "FreeBSD" : "Promise"); - goto promise_out; - } - - /* check the signature */ - if (native) { - if (strncmp(meta->promise_id, ATA_MAGIC, strlen(ATA_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "FreeBSD check1 failed\n"); - goto promise_out; - } - } - else { - if (strncmp(meta->promise_id, PR_MAGIC, strlen(PR_MAGIC))) { - if (testing || bootverbose) - device_printf(parent, "Promise check1 failed\n"); - goto promise_out; - } - } - - /* check if the checksum is OK */ - for (checksum = 0, ptr = (u_int32_t *)meta, count = 0; count < 511; count++) - checksum += *ptr++; - if (checksum != *ptr) { - if (testing || bootverbose) - device_printf(parent, "%s check2 failed\n", - native ? "FreeBSD" : "Promise"); - goto promise_out; - } - - /* check on disk integrity status */ - if (meta->raid.integrity != PR_I_VALID) { - if (testing || bootverbose) - device_printf(parent, "%s check3 failed\n", - native ? "FreeBSD" : "Promise"); - goto promise_out; - } - - if (testing || bootverbose) - ata_raid_promise_print_meta(meta); - - /* now convert Promise metadata into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto promise_out; - } - } - raid = raidp[array]; - if (raid->format && - (raid->format != (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID))) - continue; - - if ((raid->format == (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID))&& - !(meta->raid.magic_1 == (raid->magic_1))) - continue; - - /* update our knowledge about the array config based on generation */ - if (!meta->raid.generation || meta->raid.generation > raid->generation){ - switch (meta->raid.type) { - case PR_T_SPAN: - raid->type = AR_T_SPAN; - break; - - case PR_T_JBOD: - raid->type = AR_T_JBOD; - break; - - case PR_T_RAID0: - raid->type = AR_T_RAID0; - break; - - case PR_T_RAID1: - raid->type = AR_T_RAID1; - if (meta->raid.array_width > 1) - raid->type = AR_T_RAID01; - break; - - case PR_T_RAID5: - raid->type = AR_T_RAID5; - break; - - default: - device_printf(parent, "%s unknown RAID type 0x%02x\n", - native ? "FreeBSD" : "Promise", meta->raid.type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto promise_out; - } - raid->magic_1 = meta->raid.magic_1; - raid->format = (native ? AR_F_FREEBSD_RAID : AR_F_PROMISE_RAID); - raid->generation = meta->raid.generation; - raid->interleave = 1 << meta->raid.stripe_shift; - raid->width = meta->raid.array_width; - raid->total_disks = meta->raid.total_disks; - raid->heads = meta->raid.heads + 1; - raid->sectors = meta->raid.sectors; - raid->cylinders = meta->raid.cylinders + 1; - raid->total_sectors = meta->raid.total_sectors; - raid->offset_sectors = 0; - raid->rebuild_lba = meta->raid.rebuild_lba; - raid->lun = array; - if ((meta->raid.status & - (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) == - (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY)) { - raid->status |= AR_S_READY; - if (meta->raid.status & PR_S_DEGRADED) - raid->status |= AR_S_DEGRADED; - } - else - raid->status &= ~AR_S_READY; - - /* convert disk flags to our internal types */ - for (disk = 0; disk < meta->raid.total_disks; disk++) { - raid->disks[disk].dev = NULL; - raid->disks[disk].flags = 0; - *((u_int64_t *)(raid->disks[disk].serial)) = - meta->raid.disk[disk].magic_0; - disksum += meta->raid.disk[disk].flags; - if (meta->raid.disk[disk].flags & PR_F_ONLINE) - raid->disks[disk].flags |= AR_DF_ONLINE; - if (meta->raid.disk[disk].flags & PR_F_ASSIGNED) - raid->disks[disk].flags |= AR_DF_ASSIGNED; - if (meta->raid.disk[disk].flags & PR_F_SPARE) { - raid->disks[disk].flags &= ~(AR_DF_ONLINE | AR_DF_ASSIGNED); - raid->disks[disk].flags |= AR_DF_SPARE; - } - if (meta->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN)) - raid->disks[disk].flags &= ~AR_DF_ONLINE; - } - if (!disksum) { - device_printf(parent, "%s subdisks has no flags\n", - native ? "FreeBSD" : "Promise"); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto promise_out; - } - } - if (meta->raid.generation >= raid->generation) { - int disk_number = meta->raid.disk_number; - - if (raid->disks[disk_number].flags && (meta->magic_0 == - *((u_int64_t *)(raid->disks[disk_number].serial)))) { - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].flags |= AR_DF_PRESENT; - raid->disks[disk_number].sectors = meta->raid.disk_sectors; - if ((raid->disks[disk_number].flags & - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) == - (AR_DF_PRESENT | AR_DF_ASSIGNED | AR_DF_ONLINE)) { - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - } - } - } - break; - } - -promise_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_promise_write_meta(struct ar_softc *rdp) -{ - struct promise_raid_conf *meta; - struct timeval timestamp; - u_int32_t *ckptr; - int count, disk, drive, error = 0; - - if (!(meta = (struct promise_raid_conf *) - malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - rdp->generation++; - microtime(×tamp); - - for (disk = 0; disk < rdp->total_disks; disk++) { - for (count = 0; count < sizeof(struct promise_raid_conf); count++) - *(((u_int8_t *)meta) + count) = 255 - (count % 256); - meta->dummy_0 = 0x00020000; - meta->raid.disk_number = disk; - - if (rdp->disks[disk].dev) { - struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev); - struct ata_channel *ch = - device_get_softc(device_get_parent(rdp->disks[disk].dev)); - - meta->raid.channel = ch->unit; - meta->raid.device = atadev->unit; - meta->raid.disk_sectors = rdp->disks[disk].sectors; - meta->raid.disk_offset = rdp->offset_sectors; - } - else { - meta->raid.channel = 0; - meta->raid.device = 0; - meta->raid.disk_sectors = 0; - meta->raid.disk_offset = 0; - } - meta->magic_0 = PR_MAGIC0(meta->raid) | timestamp.tv_sec; - meta->magic_1 = timestamp.tv_sec >> 16; - meta->magic_2 = timestamp.tv_sec; - meta->raid.integrity = PR_I_VALID; - meta->raid.magic_0 = meta->magic_0; - meta->raid.rebuild_lba = rdp->rebuild_lba; - meta->raid.generation = rdp->generation; - - if (rdp->status & AR_S_READY) { - meta->raid.flags = (PR_F_VALID | PR_F_ASSIGNED | PR_F_ONLINE); - meta->raid.status = - (PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY); - if (rdp->status & AR_S_DEGRADED) - meta->raid.status |= PR_S_DEGRADED; - else - meta->raid.status |= PR_S_FUNCTIONAL; - } - else { - meta->raid.flags = PR_F_DOWN; - meta->raid.status = 0; - } - - switch (rdp->type) { - case AR_T_RAID0: - meta->raid.type = PR_T_RAID0; - break; - case AR_T_RAID1: - meta->raid.type = PR_T_RAID1; - break; - case AR_T_RAID01: - meta->raid.type = PR_T_RAID1; - break; - case AR_T_RAID5: - meta->raid.type = PR_T_RAID5; - break; - case AR_T_SPAN: - meta->raid.type = PR_T_SPAN; - break; - case AR_T_JBOD: - meta->raid.type = PR_T_JBOD; - break; - default: - free(meta, M_AR); - return ENODEV; - } - - meta->raid.total_disks = rdp->total_disks; - meta->raid.stripe_shift = ffs(rdp->interleave) - 1; - meta->raid.array_width = rdp->width; - meta->raid.array_number = rdp->lun; - meta->raid.total_sectors = rdp->total_sectors; - meta->raid.cylinders = rdp->cylinders - 1; - meta->raid.heads = rdp->heads - 1; - meta->raid.sectors = rdp->sectors; - meta->raid.magic_1 = (u_int64_t)meta->magic_2<<16 | meta->magic_1; - - bzero(&meta->raid.disk, 8 * 12); - for (drive = 0; drive < rdp->total_disks; drive++) { - meta->raid.disk[drive].flags = 0; - if (rdp->disks[drive].flags & AR_DF_PRESENT) - meta->raid.disk[drive].flags |= PR_F_VALID; - if (rdp->disks[drive].flags & AR_DF_ASSIGNED) - meta->raid.disk[drive].flags |= PR_F_ASSIGNED; - if (rdp->disks[drive].flags & AR_DF_ONLINE) - meta->raid.disk[drive].flags |= PR_F_ONLINE; - else - if (rdp->disks[drive].flags & AR_DF_PRESENT) - meta->raid.disk[drive].flags = (PR_F_REDIR | PR_F_DOWN); - if (rdp->disks[drive].flags & AR_DF_SPARE) - meta->raid.disk[drive].flags |= PR_F_SPARE; - meta->raid.disk[drive].dummy_0 = 0x0; - if (rdp->disks[drive].dev) { - struct ata_channel *ch = - device_get_softc(device_get_parent(rdp->disks[drive].dev)); - struct ata_device *atadev = - device_get_softc(rdp->disks[drive].dev); - - meta->raid.disk[drive].channel = ch->unit; - meta->raid.disk[drive].device = atadev->unit; - } - meta->raid.disk[drive].magic_0 = - PR_MAGIC0(meta->raid.disk[drive]) | timestamp.tv_sec; - } - - if (rdp->disks[disk].dev) { - if ((rdp->disks[disk].flags & (AR_DF_PRESENT | AR_DF_ONLINE)) == - (AR_DF_PRESENT | AR_DF_ONLINE)) { - if (rdp->format == AR_F_FREEBSD_RAID) - bcopy(ATA_MAGIC, meta->promise_id, sizeof(ATA_MAGIC)); - else - bcopy(PR_MAGIC, meta->promise_id, sizeof(PR_MAGIC)); - } - else - bzero(meta->promise_id, sizeof(meta->promise_id)); - meta->checksum = 0; - for (ckptr = (int32_t *)meta, count = 0; count < 511; count++) - meta->checksum += *ckptr++; - if (testing || bootverbose) - ata_raid_promise_print_meta(meta); - if (ata_raid_rw(rdp->disks[disk].dev, - PROMISE_LBA(rdp->disks[disk].dev), - meta, sizeof(struct promise_raid_conf), - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - free(meta, M_AR); - return error; -} - -/* Silicon Image Medley Metadata */ -static int -ata_raid_sii_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct sii_raid_conf *meta; - struct ar_softc *raid = NULL; - u_int16_t checksum, *ptr; - int array, count, disk, retval = 0; - - if (!(meta = (struct sii_raid_conf *) - malloc(sizeof(struct sii_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, SII_LBA(parent), - meta, sizeof(struct sii_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "Silicon Image read metadata failed\n"); - goto sii_out; - } - - /* check if this is a Silicon Image (Medley) RAID struct */ - for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 160; count++) - checksum += *ptr++; - if (checksum) { - if (testing || bootverbose) - device_printf(parent, "Silicon Image check1 failed\n"); - goto sii_out; - } - - for (checksum = 0, ptr = (u_int16_t *)meta, count = 0; count < 256; count++) - checksum += *ptr++; - if (checksum != meta->checksum_1) { - if (testing || bootverbose) - device_printf(parent, "Silicon Image check2 failed\n"); - goto sii_out; - } - - /* check verison */ - if (meta->version_major != 0x0002 || - (meta->version_minor != 0x0000 && meta->version_minor != 0x0001)) { - if (testing || bootverbose) - device_printf(parent, "Silicon Image check3 failed\n"); - goto sii_out; - } - - if (testing || bootverbose) - ata_raid_sii_print_meta(meta); - - /* now convert Silicon Image meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto sii_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_SII_RAID)) - continue; - - if (raid->format == AR_F_SII_RAID && - (raid->magic_0 != *((u_int64_t *)meta->timestamp))) { - continue; - } - - /* update our knowledge about the array config based on generation */ - if (!meta->generation || meta->generation > raid->generation) { - switch (meta->type) { - case SII_T_RAID0: - raid->type = AR_T_RAID0; - break; - - case SII_T_RAID1: - raid->type = AR_T_RAID1; - break; - - case SII_T_RAID01: - raid->type = AR_T_RAID01; - break; - - case SII_T_SPARE: - device_printf(parent, "Silicon Image SPARE disk\n"); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto sii_out; - - default: - device_printf(parent,"Silicon Image unknown RAID type 0x%02x\n", - meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto sii_out; - } - raid->magic_0 = *((u_int64_t *)meta->timestamp); - raid->format = AR_F_SII_RAID; - raid->generation = meta->generation; - raid->interleave = meta->stripe_sectors; - raid->width = (meta->raid0_disks != 0xff) ? meta->raid0_disks : 1; - raid->total_disks = - ((meta->raid0_disks != 0xff) ? meta->raid0_disks : 0) + - ((meta->raid1_disks != 0xff) ? meta->raid1_disks : 0); - raid->total_sectors = meta->total_sectors; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = meta->rebuild_lba; - raid->lun = array; - strncpy(raid->name, meta->name, - min(sizeof(raid->name), sizeof(meta->name))); - - /* clear out any old info */ - if (raid->generation) { - for (disk = 0; disk < raid->total_disks; disk++) { - raid->disks[disk].dev = NULL; - raid->disks[disk].flags = 0; - } - } - } - if (meta->generation >= raid->generation) { - /* XXX SOS add check for the right physical disk by serial# */ - if (meta->status & SII_S_READY) { - int disk_number = (raid->type == AR_T_RAID01) ? - meta->raid1_ident + (meta->raid0_ident << 1) : - meta->disk_number; - - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].sectors = - raid->total_sectors / raid->width; - raid->disks[disk_number].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - retval = 1; - } - } - break; - } - -sii_out: - free(meta, M_AR); - return retval; -} - -/* Silicon Integrated Systems Metadata */ -static int -ata_raid_sis_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct sis_raid_conf *meta; - struct ar_softc *raid = NULL; - int array, disk_number, drive, retval = 0; - - if (!(meta = (struct sis_raid_conf *) - malloc(sizeof(struct sis_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, SIS_LBA(parent), - meta, sizeof(struct sis_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, - "Silicon Integrated Systems read metadata failed\n"); - } - - /* check for SiS magic */ - if (meta->magic != SIS_MAGIC) { - if (testing || bootverbose) - device_printf(parent, - "Silicon Integrated Systems check1 failed\n"); - goto sis_out; - } - - if (testing || bootverbose) - ata_raid_sis_print_meta(meta); - - /* now convert SiS meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto sis_out; - } - } - - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_SIS_RAID)) - continue; - - if ((raid->format == AR_F_SIS_RAID) && - ((raid->magic_0 != meta->controller_pci_id) || - (raid->magic_1 != meta->timestamp))) { - continue; - } - - switch (meta->type_total_disks & SIS_T_MASK) { - case SIS_T_JBOD: - raid->type = AR_T_JBOD; - raid->width = (meta->type_total_disks & SIS_D_MASK); - raid->total_sectors += SIS_LBA(parent); - break; - - case SIS_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = (meta->type_total_disks & SIS_D_MASK); - if (!raid->total_sectors || - (raid->total_sectors > (raid->width * SIS_LBA(parent)))) - raid->total_sectors = raid->width * SIS_LBA(parent); - break; - - case SIS_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = 1; - if (!raid->total_sectors || (raid->total_sectors > SIS_LBA(parent))) - raid->total_sectors = SIS_LBA(parent); - break; - - default: - device_printf(parent, "Silicon Integrated Systems " - "unknown RAID type 0x%08x\n", meta->magic); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto sis_out; - } - raid->magic_0 = meta->controller_pci_id; - raid->magic_1 = meta->timestamp; - raid->format = AR_F_SIS_RAID; - raid->generation = 0; - raid->interleave = meta->stripe_sectors; - raid->total_disks = (meta->type_total_disks & SIS_D_MASK); - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - /* XXX SOS if total_disks > 2 this doesn't float */ - if (((meta->disks & SIS_D_MASTER) >> 4) == meta->disk_number) - disk_number = 0; - else - disk_number = 1; - - for (drive = 0; drive < raid->total_disks; drive++) { - raid->disks[drive].sectors = raid->total_sectors/raid->width; - if (drive == disk_number) { - raid->disks[disk_number].dev = parent; - raid->disks[disk_number].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk_number; - } - } - retval = 1; - break; - } - -sis_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_sis_write_meta(struct ar_softc *rdp) -{ - struct sis_raid_conf *meta; - struct timeval timestamp; - int disk, error = 0; - - if (!(meta = (struct sis_raid_conf *) - malloc(sizeof(struct sis_raid_conf), M_AR, M_NOWAIT | M_ZERO))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - rdp->generation++; - microtime(×tamp); - - meta->magic = SIS_MAGIC; - /* XXX SOS if total_disks > 2 this doesn't float */ - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - struct ata_channel *ch = - device_get_softc(device_get_parent(rdp->disks[disk].dev)); - struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev); - int disk_number = 1 + atadev->unit + (ch->unit << 1); - - meta->disks |= disk_number << ((1 - disk) << 2); - } - } - switch (rdp->type) { - case AR_T_JBOD: - meta->type_total_disks = SIS_T_JBOD; - break; - - case AR_T_RAID0: - meta->type_total_disks = SIS_T_RAID0; - break; - - case AR_T_RAID1: - meta->type_total_disks = SIS_T_RAID1; - break; - - default: - free(meta, M_AR); - return ENODEV; - } - meta->type_total_disks |= (rdp->total_disks & SIS_D_MASK); - meta->stripe_sectors = rdp->interleave; - meta->timestamp = timestamp.tv_sec; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - struct ata_channel *ch = - device_get_softc(device_get_parent(rdp->disks[disk].dev)); - struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev); - - meta->controller_pci_id = - (pci_get_vendor(GRANDPARENT(rdp->disks[disk].dev)) << 16) | - pci_get_device(GRANDPARENT(rdp->disks[disk].dev)); - bcopy(atadev->param.model, meta->model, sizeof(meta->model)); - - /* XXX SOS if total_disks > 2 this may not float */ - meta->disk_number = 1 + atadev->unit + (ch->unit << 1); - - if (testing || bootverbose) - ata_raid_sis_print_meta(meta); - - if (ata_raid_rw(rdp->disks[disk].dev, - SIS_LBA(rdp->disks[disk].dev), - meta, sizeof(struct sis_raid_conf), - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - free(meta, M_AR); - return error; -} - -/* VIA Tech V-RAID Metadata */ -static int -ata_raid_via_read_meta(device_t dev, struct ar_softc **raidp) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - device_t parent = device_get_parent(dev); - struct via_raid_conf *meta; - struct ar_softc *raid = NULL; - u_int8_t checksum, *ptr; - int array, count, disk, retval = 0; - - if (!(meta = (struct via_raid_conf *) - malloc(sizeof(struct via_raid_conf), M_AR, M_NOWAIT | M_ZERO))) - return ENOMEM; - - if (ata_raid_rw(parent, VIA_LBA(parent), - meta, sizeof(struct via_raid_conf), ATA_R_READ)) { - if (testing || bootverbose) - device_printf(parent, "VIA read metadata failed\n"); - goto via_out; - } - - /* check if this is a VIA RAID struct */ - if (meta->magic != VIA_MAGIC) { - if (testing || bootverbose) - device_printf(parent, "VIA check1 failed\n"); - goto via_out; - } - - /* calculate checksum and compare for valid */ - for (checksum = 0, ptr = (u_int8_t *)meta, count = 0; count < 50; count++) - checksum += *ptr++; - if (checksum != meta->checksum) { - if (testing || bootverbose) - device_printf(parent, "VIA check2 failed\n"); - goto via_out; - } - - if (testing || bootverbose) - ata_raid_via_print_meta(meta); - - /* now convert VIA meta into our generic form */ - for (array = 0; array < MAX_ARRAYS; array++) { - if (!raidp[array]) { - raidp[array] = - (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, - M_NOWAIT | M_ZERO); - if (!raidp[array]) { - device_printf(parent, "failed to allocate metadata storage\n"); - goto via_out; - } - } - raid = raidp[array]; - if (raid->format && (raid->format != AR_F_VIA_RAID)) - continue; - - if (raid->format == AR_F_VIA_RAID && (raid->magic_0 != meta->disks[0])) - continue; - - switch (meta->type & VIA_T_MASK) { - case VIA_T_RAID0: - raid->type = AR_T_RAID0; - raid->width = meta->stripe_layout & VIA_L_DISKS; - if (!raid->total_sectors || - (raid->total_sectors > (raid->width * meta->disk_sectors))) - raid->total_sectors = raid->width * meta->disk_sectors; - break; - - case VIA_T_RAID1: - raid->type = AR_T_RAID1; - raid->width = 1; - raid->total_sectors = meta->disk_sectors; - break; - - case VIA_T_RAID01: - raid->type = AR_T_RAID01; - raid->width = meta->stripe_layout & VIA_L_DISKS; - if (!raid->total_sectors || - (raid->total_sectors > (raid->width * meta->disk_sectors))) - raid->total_sectors = raid->width * meta->disk_sectors; - break; - - case VIA_T_RAID5: - raid->type = AR_T_RAID5; - raid->width = meta->stripe_layout & VIA_L_DISKS; - if (!raid->total_sectors || - (raid->total_sectors > ((raid->width - 1)*meta->disk_sectors))) - raid->total_sectors = (raid->width - 1) * meta->disk_sectors; - break; - - case VIA_T_SPAN: - raid->type = AR_T_SPAN; - raid->width = 1; - raid->total_sectors += meta->disk_sectors; - break; - - default: - device_printf(parent,"VIA unknown RAID type 0x%02x\n", meta->type); - free(raidp[array], M_AR); - raidp[array] = NULL; - goto via_out; - } - raid->magic_0 = meta->disks[0]; - raid->format = AR_F_VIA_RAID; - raid->generation = 0; - raid->interleave = - 0x08 << ((meta->stripe_layout & VIA_L_MASK) >> VIA_L_SHIFT); - for (count = 0, disk = 0; disk < 8; disk++) - if (meta->disks[disk]) - count++; - raid->total_disks = count; - raid->heads = 255; - raid->sectors = 63; - raid->cylinders = raid->total_sectors / (63 * 255); - raid->offset_sectors = 0; - raid->rebuild_lba = 0; - raid->lun = array; - - for (disk = 0; disk < raid->total_disks; disk++) { - if (meta->disks[disk] == meta->disk_id) { - raid->disks[disk].dev = parent; - bcopy(&meta->disk_id, raid->disks[disk].serial, - sizeof(u_int32_t)); - raid->disks[disk].sectors = meta->disk_sectors; - raid->disks[disk].flags = - (AR_DF_ONLINE | AR_DF_PRESENT | AR_DF_ASSIGNED); - ars->raid[raid->volume] = raid; - ars->disk_number[raid->volume] = disk; - retval = 1; - break; - } - } - break; - } - -via_out: - free(meta, M_AR); - return retval; -} - -static int -ata_raid_via_write_meta(struct ar_softc *rdp) -{ - struct via_raid_conf *meta; - int disk, error = 0; - - if (!(meta = (struct via_raid_conf *) - malloc(sizeof(struct via_raid_conf), M_AR, M_NOWAIT | M_ZERO))) { - printf("ar%d: failed to allocate metadata storage\n", rdp->lun); - return ENOMEM; - } - - rdp->generation++; - - meta->magic = VIA_MAGIC; - meta->dummy_0 = 0x02; - switch (rdp->type) { - case AR_T_SPAN: - meta->type = VIA_T_SPAN; - meta->stripe_layout = (rdp->total_disks & VIA_L_DISKS); - break; - - case AR_T_RAID0: - meta->type = VIA_T_RAID0; - meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK); - meta->stripe_layout |= (rdp->total_disks & VIA_L_DISKS); - break; - - case AR_T_RAID1: - meta->type = VIA_T_RAID1; - meta->stripe_layout = (rdp->total_disks & VIA_L_DISKS); - break; - - case AR_T_RAID5: - meta->type = VIA_T_RAID5; - meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK); - meta->stripe_layout |= (rdp->total_disks & VIA_L_DISKS); - break; - - case AR_T_RAID01: - meta->type = VIA_T_RAID01; - meta->stripe_layout = ((rdp->interleave >> 1) & VIA_L_MASK); - meta->stripe_layout |= (rdp->width & VIA_L_DISKS); - break; - - default: - free(meta, M_AR); - return ENODEV; - } - meta->type |= VIA_T_BOOTABLE; /* XXX SOS */ - meta->disk_sectors = - rdp->total_sectors / (rdp->width - (rdp->type == AR_RAID5)); - for (disk = 0; disk < rdp->total_disks; disk++) - meta->disks[disk] = (u_int32_t)(uintptr_t)rdp->disks[disk].dev; - - for (disk = 0; disk < rdp->total_disks; disk++) { - if (rdp->disks[disk].dev) { - u_int8_t *ptr; - int count; - - meta->disk_index = disk * sizeof(u_int32_t); - if (rdp->type == AR_T_RAID01) - meta->disk_index = ((meta->disk_index & 0x08) << 2) | - (meta->disk_index & ~0x08); - meta->disk_id = meta->disks[disk]; - meta->checksum = 0; - for (ptr = (u_int8_t *)meta, count = 0; count < 50; count++) - meta->checksum += *ptr++; - - if (testing || bootverbose) - ata_raid_via_print_meta(meta); - - if (ata_raid_rw(rdp->disks[disk].dev, - VIA_LBA(rdp->disks[disk].dev), - meta, sizeof(struct via_raid_conf), - ATA_R_WRITE | ATA_R_DIRECT)) { - device_printf(rdp->disks[disk].dev, "write metadata failed\n"); - error = EIO; - } - } - } - free(meta, M_AR); - return error; -} - -static struct ata_request * -ata_raid_init_request(device_t dev, struct ar_softc *rdp, struct bio *bio) -{ - struct ata_request *request; - - if (!(request = ata_alloc_request())) { - printf("FAILURE - out of memory in ata_raid_init_request\n"); - return NULL; - } - request->dev = dev; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 2; - request->callback = ata_raid_done; - request->driver = rdp; - request->bio = bio; - switch (request->bio->bio_cmd) { - case BIO_READ: - request->flags = ATA_R_READ; - break; - case BIO_WRITE: - request->flags = ATA_R_WRITE; - break; - case BIO_FLUSH: - request->flags = ATA_R_CONTROL; - break; - } - return request; -} - -static int -ata_raid_send_request(struct ata_request *request) -{ - struct ata_device *atadev = device_get_softc(request->dev); - - request->transfersize = min(request->bytecount, atadev->max_iosize); - if (request->flags & ATA_R_READ) { - if (atadev->mode >= ATA_DMA) { - request->flags |= ATA_R_DMA; - request->u.ata.command = ATA_READ_DMA; - } - else if (atadev->max_iosize > DEV_BSIZE) - request->u.ata.command = ATA_READ_MUL; - else - request->u.ata.command = ATA_READ; - } - else if (request->flags & ATA_R_WRITE) { - if (atadev->mode >= ATA_DMA) { - request->flags |= ATA_R_DMA; - request->u.ata.command = ATA_WRITE_DMA; - } - else if (atadev->max_iosize > DEV_BSIZE) - request->u.ata.command = ATA_WRITE_MUL; - else - request->u.ata.command = ATA_WRITE; - } - else { - device_printf(request->dev, "FAILURE - unknown IO operation\n"); - ata_free_request(request); - return EIO; - } - request->flags |= (ATA_R_ORDERED | ATA_R_THREAD); - ata_queue_request(request); - return 0; -} - -static int -ata_raid_rw(device_t dev, u_int64_t lba, void *data, u_int bcount, int flags) -{ - struct ata_device *atadev = device_get_softc(dev); - struct ata_request *request; - int error; - - if (bcount % DEV_BSIZE) { - device_printf(dev, "FAILURE - transfers must be modulo sectorsize\n"); - return ENOMEM; - } - - if (!(request = ata_alloc_request())) { - device_printf(dev, "FAILURE - out of memory in ata_raid_rw\n"); - return ENOMEM; - } - - /* setup request */ - request->dev = dev; - request->timeout = ATA_REQUEST_TIMEOUT; - request->retries = 0; - request->data = data; - request->bytecount = bcount; - request->transfersize = DEV_BSIZE; - request->u.ata.lba = lba; - request->u.ata.count = request->bytecount / DEV_BSIZE; - request->flags = flags; - - if (flags & ATA_R_READ) { - if (atadev->mode >= ATA_DMA) { - request->u.ata.command = ATA_READ_DMA; - request->flags |= ATA_R_DMA; - } - else - request->u.ata.command = ATA_READ; - ata_queue_request(request); - } - else if (flags & ATA_R_WRITE) { - if (atadev->mode >= ATA_DMA) { - request->u.ata.command = ATA_WRITE_DMA; - request->flags |= ATA_R_DMA; - } - else - request->u.ata.command = ATA_WRITE; - ata_queue_request(request); - } - else { - device_printf(dev, "FAILURE - unknown IO operation\n"); - request->result = EIO; - } - error = request->result; - ata_free_request(request); - return error; -} - -/* - * module handeling - */ -static int -ata_raid_subdisk_probe(device_t dev) -{ - device_quiet(dev); - return 0; -} - -static int -ata_raid_subdisk_attach(device_t dev) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - int volume; - - for (volume = 0; volume < MAX_VOLUMES; volume++) { - ars->raid[volume] = NULL; - ars->disk_number[volume] = -1; - } - ata_raid_read_metadata(dev); - return 0; -} - -static int -ata_raid_subdisk_detach(device_t dev) -{ - struct ata_raid_subdisk *ars = device_get_softc(dev); - int volume; - - for (volume = 0; volume < MAX_VOLUMES; volume++) { - if (ars->raid[volume]) { - ars->raid[volume]->disks[ars->disk_number[volume]].flags &= - ~(AR_DF_PRESENT | AR_DF_ONLINE); - ars->raid[volume]->disks[ars->disk_number[volume]].dev = NULL; - if (mtx_initialized(&ars->raid[volume]->lock)) - ata_raid_config_changed(ars->raid[volume], 1); - ars->raid[volume] = NULL; - ars->disk_number[volume] = -1; - } - } - return 0; -} - -static device_method_t ata_raid_sub_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, ata_raid_subdisk_probe), - DEVMETHOD(device_attach, ata_raid_subdisk_attach), - DEVMETHOD(device_detach, ata_raid_subdisk_detach), - DEVMETHOD_END -}; - -static driver_t ata_raid_sub_driver = { - "subdisk", - ata_raid_sub_methods, - sizeof(struct ata_raid_subdisk) -}; - -DRIVER_MODULE(subdisk, ad, ata_raid_sub_driver, ata_raid_sub_devclass, NULL, NULL); - -static int -ata_raid_module_event_handler(module_t mod, int what, void *arg) -{ - int i; - - switch (what) { - case MOD_LOAD: - if (testing || bootverbose) - printf("ATA PseudoRAID loaded\n"); -#if 0 - /* setup table to hold metadata for all ATA PseudoRAID arrays */ - ata_raid_arrays = malloc(sizeof(struct ar_soft *) * MAX_ARRAYS, - M_AR, M_NOWAIT | M_ZERO); - if (!ata_raid_arrays) { - printf("ataraid: no memory for metadata storage\n"); - return ENOMEM; - } -#endif - /* attach found PseudoRAID arrays */ - for (i = 0; i < MAX_ARRAYS; i++) { - struct ar_softc *rdp = ata_raid_arrays[i]; - - if (!rdp || !rdp->format) - continue; - if (testing || bootverbose) - ata_raid_print_meta(rdp); - ata_raid_attach(rdp, 0); - } - ata_raid_ioctl_func = ata_raid_ioctl; - return 0; - - case MOD_UNLOAD: - /* detach found PseudoRAID arrays */ - for (i = 0; i < MAX_ARRAYS; i++) { - struct ar_softc *rdp = ata_raid_arrays[i]; - - if (!rdp || !rdp->status) - continue; - if (mtx_initialized(&rdp->lock)) - mtx_destroy(&rdp->lock); - if (rdp->disk) - disk_destroy(rdp->disk); - } - if (testing || bootverbose) - printf("ATA PseudoRAID unloaded\n"); -#if 0 - free(ata_raid_arrays, M_AR); -#endif - ata_raid_ioctl_func = NULL; - return 0; - - default: - return EOPNOTSUPP; - } -} - -static moduledata_t ata_raid_moduledata = - { "ataraid", ata_raid_module_event_handler, NULL }; -DECLARE_MODULE(ata, ata_raid_moduledata, SI_SUB_RAID, SI_ORDER_FIRST); -MODULE_VERSION(ataraid, 1); -MODULE_DEPEND(ataraid, ata, 1, 1, 1); -MODULE_DEPEND(ataraid, ad, 1, 1, 1); - -static char * -ata_raid_format(struct ar_softc *rdp) -{ - switch (rdp->format) { - case AR_F_FREEBSD_RAID: return "FreeBSD PseudoRAID"; - case AR_F_ADAPTEC_RAID: return "Adaptec HostRAID"; - case AR_F_DDF_RAID: return "DDF"; - case AR_F_HPTV2_RAID: return "HighPoint v2 RocketRAID"; - case AR_F_HPTV3_RAID: return "HighPoint v3 RocketRAID"; - case AR_F_INTEL_RAID: return "Intel MatrixRAID"; - case AR_F_ITE_RAID: return "Integrated Technology Express"; - case AR_F_JMICRON_RAID: return "JMicron Technology Corp"; - case AR_F_LSIV2_RAID: return "LSILogic v2 MegaRAID"; - case AR_F_LSIV3_RAID: return "LSILogic v3 MegaRAID"; - case AR_F_NVIDIA_RAID: return "nVidia MediaShield"; - case AR_F_PROMISE_RAID: return "Promise Fasttrak"; - case AR_F_SII_RAID: return "Silicon Image Medley"; - case AR_F_SIS_RAID: return "Silicon Integrated Systems"; - case AR_F_VIA_RAID: return "VIA Tech V-RAID"; - default: return "UNKNOWN"; - } -} - -static char * -ata_raid_type(struct ar_softc *rdp) -{ - switch (rdp->type) { - case AR_T_JBOD: return "JBOD"; - case AR_T_SPAN: return "SPAN"; - case AR_T_RAID0: return "RAID0"; - case AR_T_RAID1: return "RAID1"; - case AR_T_RAID3: return "RAID3"; - case AR_T_RAID4: return "RAID4"; - case AR_T_RAID5: return "RAID5"; - case AR_T_RAID01: return "RAID0+1"; - default: return "UNKNOWN"; - } -} - -static char * -ata_raid_flags(struct ar_softc *rdp) -{ - switch (rdp->status & (AR_S_READY | AR_S_DEGRADED | AR_S_REBUILDING)) { - case AR_S_READY: return "READY"; - case AR_S_READY | AR_S_DEGRADED: return "DEGRADED"; - case AR_S_READY | AR_S_REBUILDING: - case AR_S_READY | AR_S_DEGRADED | AR_S_REBUILDING: return "REBUILDING"; - default: return "BROKEN"; - } -} - -/* debugging gunk */ -static void -ata_raid_print_meta(struct ar_softc *raid) -{ - int i; - - printf("********** ATA PseudoRAID ar%d Metadata **********\n", raid->lun); - printf("=================================================\n"); - printf("format %s\n", ata_raid_format(raid)); - printf("type %s\n", ata_raid_type(raid)); - printf("flags 0x%02x %b\n", raid->status, raid->status, - "\20\3REBUILDING\2DEGRADED\1READY\n"); - printf("magic_0 0x%016jx\n", raid->magic_0); - printf("magic_1 0x%016jx\n",raid->magic_1); - printf("generation %u\n", raid->generation); - printf("total_sectors %ju\n", raid->total_sectors); - printf("offset_sectors %ju\n", raid->offset_sectors); - printf("heads %u\n", raid->heads); - printf("sectors %u\n", raid->sectors); - printf("cylinders %u\n", raid->cylinders); - printf("width %u\n", raid->width); - printf("interleave %u\n", raid->interleave); - printf("total_disks %u\n", raid->total_disks); - for (i = 0; i < raid->total_disks; i++) { - printf(" disk %d: flags = 0x%02x %b\n", i, raid->disks[i].flags, - raid->disks[i].flags, "\20\4ONLINE\3SPARE\2ASSIGNED\1PRESENT\n"); - if (raid->disks[i].dev) { - printf(" "); - device_printf(raid->disks[i].dev, " sectors %jd\n", - raid->disks[i].sectors); - } - } - printf("=================================================\n"); -} - -static char * -ata_raid_adaptec_type(int type) -{ - static char buffer[16]; - - switch (type) { - case ADP_T_RAID0: return "RAID0"; - case ADP_T_RAID1: return "RAID1"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_adaptec_print_meta(struct adaptec_raid_conf *meta) -{ - int i; - - printf("********* ATA Adaptec HostRAID Metadata *********\n"); - printf("magic_0 <0x%08x>\n", be32toh(meta->magic_0)); - printf("generation 0x%08x\n", be32toh(meta->generation)); - printf("dummy_0 0x%04x\n", be16toh(meta->dummy_0)); - printf("total_configs %u\n", be16toh(meta->total_configs)); - printf("dummy_1 0x%04x\n", be16toh(meta->dummy_1)); - printf("checksum 0x%04x\n", be16toh(meta->checksum)); - printf("dummy_2 0x%08x\n", be32toh(meta->dummy_2)); - printf("dummy_3 0x%08x\n", be32toh(meta->dummy_3)); - printf("flags 0x%08x\n", be32toh(meta->flags)); - printf("timestamp 0x%08x\n", be32toh(meta->timestamp)); - printf("dummy_4 0x%08x 0x%08x 0x%08x 0x%08x\n", - be32toh(meta->dummy_4[0]), be32toh(meta->dummy_4[1]), - be32toh(meta->dummy_4[2]), be32toh(meta->dummy_4[3])); - printf("dummy_5 0x%08x 0x%08x 0x%08x 0x%08x\n", - be32toh(meta->dummy_5[0]), be32toh(meta->dummy_5[1]), - be32toh(meta->dummy_5[2]), be32toh(meta->dummy_5[3])); - - for (i = 0; i < be16toh(meta->total_configs); i++) { - printf(" %d total_disks %u\n", i, - be16toh(meta->configs[i].disk_number)); - printf(" %d generation %u\n", i, - be16toh(meta->configs[i].generation)); - printf(" %d magic_0 0x%08x\n", i, - be32toh(meta->configs[i].magic_0)); - printf(" %d dummy_0 0x%02x\n", i, meta->configs[i].dummy_0); - printf(" %d type %s\n", i, - ata_raid_adaptec_type(meta->configs[i].type)); - printf(" %d dummy_1 0x%02x\n", i, meta->configs[i].dummy_1); - printf(" %d flags %d\n", i, - be32toh(meta->configs[i].flags)); - printf(" %d dummy_2 0x%02x\n", i, meta->configs[i].dummy_2); - printf(" %d dummy_3 0x%02x\n", i, meta->configs[i].dummy_3); - printf(" %d dummy_4 0x%02x\n", i, meta->configs[i].dummy_4); - printf(" %d dummy_5 0x%02x\n", i, meta->configs[i].dummy_5); - printf(" %d disk_number %u\n", i, - be32toh(meta->configs[i].disk_number)); - printf(" %d dummy_6 0x%08x\n", i, - be32toh(meta->configs[i].dummy_6)); - printf(" %d sectors %u\n", i, - be32toh(meta->configs[i].sectors)); - printf(" %d stripe_shift %u\n", i, - be16toh(meta->configs[i].stripe_shift)); - printf(" %d dummy_7 0x%08x\n", i, - be32toh(meta->configs[i].dummy_7)); - printf(" %d dummy_8 0x%08x 0x%08x 0x%08x 0x%08x\n", i, - be32toh(meta->configs[i].dummy_8[0]), - be32toh(meta->configs[i].dummy_8[1]), - be32toh(meta->configs[i].dummy_8[2]), - be32toh(meta->configs[i].dummy_8[3])); - printf(" %d name <%s>\n", i, meta->configs[i].name); - } - printf("magic_1 <0x%08x>\n", be32toh(meta->magic_1)); - printf("magic_2 <0x%08x>\n", be32toh(meta->magic_2)); - printf("magic_3 <0x%08x>\n", be32toh(meta->magic_3)); - printf("magic_4 <0x%08x>\n", be32toh(meta->magic_4)); - printf("=================================================\n"); -} - -static void -ata_raid_ddf_print_meta(uint8_t *meta) -{ - struct ddf_header *hdr; - struct ddf_cd_record *cd; - struct ddf_pd_record *pdr; - struct ddf_pd_entry *pde; - struct ddf_vd_record *vdr; - struct ddf_vd_entry *vde; - struct ddf_pdd_record *pdd; - uint64_t (*ddf64toh)(uint64_t) = NULL; - uint32_t (*ddf32toh)(uint32_t) = NULL; - uint16_t (*ddf16toh)(uint16_t) = NULL; - uint8_t *cr; - char *r; - - /* Check if this is a DDF RAID struct */ - hdr = (struct ddf_header *)meta; - if (be32toh(hdr->Signature) == DDF_HEADER_SIGNATURE) { - ddf64toh = ddfbe64toh; - ddf32toh = ddfbe32toh; - ddf16toh = ddfbe16toh; - } else { - ddf64toh = ddfle64toh; - ddf32toh = ddfle32toh; - ddf16toh = ddfle16toh; - } - - hdr = (struct ddf_header*)meta; - cd = (struct ddf_cd_record*)(meta + ddf32toh(hdr->cd_section) *DEV_BSIZE); - pdr = (struct ddf_pd_record*)(meta + ddf32toh(hdr->pdr_section)*DEV_BSIZE); - vdr = (struct ddf_vd_record*)(meta + ddf32toh(hdr->vdr_section)*DEV_BSIZE); - cr = (uint8_t *)(meta + ddf32toh(hdr->cr_section) * DEV_BSIZE); - pdd = (struct ddf_pdd_record*)(meta + ddf32toh(hdr->pdd_section)*DEV_BSIZE); - pde = NULL; - vde = NULL; - - printf("********* ATA DDF Metadata *********\n"); - printf("**** Header ****\n"); - r = (char *)&hdr->DDF_rev[0]; - printf("DDF_rev= %8.8s Sequence_Number= 0x%x Open_Flag= 0x%x\n", r, - ddf32toh(hdr->Sequence_Number), hdr->Open_Flag); - printf("Primary Header LBA= %llu Header_Type = 0x%x\n", - (unsigned long long)ddf64toh(hdr->Primary_Header_LBA), - hdr->Header_Type); - printf("Max_PD_Entries= %d Max_VD_Entries= %d Max_Partitions= %d " - "CR_Length= %d\n", ddf16toh(hdr->Max_PD_Entries), - ddf16toh(hdr->Max_VD_Entries), ddf16toh(hdr->Max_Partitions), - ddf16toh(hdr->Configuration_Record_Length)); - printf("CD= %d:%d PDR= %d:%d VDR= %d:%d CR= %d:%d PDD= %d%d\n", - ddf32toh(hdr->cd_section), ddf32toh(hdr->cd_length), - ddf32toh(hdr->pdr_section), ddf32toh(hdr->pdr_length), - ddf32toh(hdr->vdr_section), ddf32toh(hdr->vdr_length), - ddf32toh(hdr->cr_section), ddf32toh(hdr->cr_length), - ddf32toh(hdr->pdd_section), ddf32toh(hdr->pdd_length)); - printf("**** Controler Data ****\n"); - r = (char *)&cd->Product_ID[0]; - printf("Product_ID: %16.16s\n", r); - printf("Vendor 0x%x, Device 0x%x, SubVendor 0x%x, Sub_Device 0x%x\n", - ddf16toh(cd->Controller_Type.Vendor_ID), - ddf16toh(cd->Controller_Type.Device_ID), - ddf16toh(cd->Controller_Type.SubVendor_ID), - ddf16toh(cd->Controller_Type.SubDevice_ID)); -} - -static char * -ata_raid_hptv2_type(int type) -{ - static char buffer[16]; - - switch (type) { - case HPTV2_T_RAID0: return "RAID0"; - case HPTV2_T_RAID1: return "RAID1"; - case HPTV2_T_RAID01_RAID0: return "RAID01_RAID0"; - case HPTV2_T_SPAN: return "SPAN"; - case HPTV2_T_RAID_3: return "RAID3"; - case HPTV2_T_RAID_5: return "RAID5"; - case HPTV2_T_JBOD: return "JBOD"; - case HPTV2_T_RAID01_RAID1: return "RAID01_RAID1"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_hptv2_print_meta(struct hptv2_raid_conf *meta) -{ - int i; - - printf("****** ATA Highpoint V2 RocketRAID Metadata *****\n"); - printf("magic 0x%08x\n", meta->magic); - printf("magic_0 0x%08x\n", meta->magic_0); - printf("magic_1 0x%08x\n", meta->magic_1); - printf("order 0x%08x\n", meta->order); - printf("array_width %u\n", meta->array_width); - printf("stripe_shift %u\n", meta->stripe_shift); - printf("type %s\n", ata_raid_hptv2_type(meta->type)); - printf("disk_number %u\n", meta->disk_number); - printf("total_sectors %u\n", meta->total_sectors); - printf("disk_mode 0x%08x\n", meta->disk_mode); - printf("boot_mode 0x%08x\n", meta->boot_mode); - printf("boot_disk 0x%02x\n", meta->boot_disk); - printf("boot_protect 0x%02x\n", meta->boot_protect); - printf("log_entries 0x%02x\n", meta->error_log_entries); - printf("log_index 0x%02x\n", meta->error_log_index); - if (meta->error_log_entries) { - printf(" timestamp reason disk status sectors lba\n"); - for (i = meta->error_log_index; - i < meta->error_log_index + meta->error_log_entries; i++) - printf(" 0x%08x 0x%02x 0x%02x 0x%02x 0x%02x 0x%08x\n", - meta->errorlog[i%32].timestamp, - meta->errorlog[i%32].reason, - meta->errorlog[i%32].disk, meta->errorlog[i%32].status, - meta->errorlog[i%32].sectors, meta->errorlog[i%32].lba); - } - printf("rebuild_lba 0x%08x\n", meta->rebuild_lba); - printf("dummy_1 0x%02x\n", meta->dummy_1); - printf("name_1 <%.15s>\n", meta->name_1); - printf("dummy_2 0x%02x\n", meta->dummy_2); - printf("name_2 <%.15s>\n", meta->name_2); - printf("=================================================\n"); -} - -static char * -ata_raid_hptv3_type(int type) -{ - static char buffer[16]; - - switch (type) { - case HPTV3_T_SPARE: return "SPARE"; - case HPTV3_T_JBOD: return "JBOD"; - case HPTV3_T_SPAN: return "SPAN"; - case HPTV3_T_RAID0: return "RAID0"; - case HPTV3_T_RAID1: return "RAID1"; - case HPTV3_T_RAID3: return "RAID3"; - case HPTV3_T_RAID5: return "RAID5"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_hptv3_print_meta(struct hptv3_raid_conf *meta) -{ - int i; - - printf("****** ATA Highpoint V3 RocketRAID Metadata *****\n"); - printf("magic 0x%08x\n", meta->magic); - printf("magic_0 0x%08x\n", meta->magic_0); - printf("checksum_0 0x%02x\n", meta->checksum_0); - printf("mode 0x%02x\n", meta->mode); - printf("user_mode 0x%02x\n", meta->user_mode); - printf("config_entries 0x%02x\n", meta->config_entries); - for (i = 0; i < meta->config_entries; i++) { - printf("config %d:\n", i); - printf(" total_sectors %ju\n", - meta->configs[0].total_sectors + - ((u_int64_t)meta->configs_high[0].total_sectors << 32)); - printf(" type %s\n", - ata_raid_hptv3_type(meta->configs[i].type)); - printf(" total_disks %u\n", meta->configs[i].total_disks); - printf(" disk_number %u\n", meta->configs[i].disk_number); - printf(" stripe_shift %u\n", meta->configs[i].stripe_shift); - printf(" status %b\n", meta->configs[i].status, - "\20\2RAID5\1NEED_REBUILD\n"); - printf(" critical_disks %u\n", meta->configs[i].critical_disks); - printf(" rebuild_lba %ju\n", - meta->configs_high[0].rebuild_lba + - ((u_int64_t)meta->configs_high[0].rebuild_lba << 32)); - } - printf("name <%.16s>\n", meta->name); - printf("timestamp 0x%08x\n", meta->timestamp); - printf("description <%.16s>\n", meta->description); - printf("creator <%.16s>\n", meta->creator); - printf("checksum_1 0x%02x\n", meta->checksum_1); - printf("dummy_0 0x%02x\n", meta->dummy_0); - printf("dummy_1 0x%02x\n", meta->dummy_1); - printf("flags %b\n", meta->flags, - "\20\4RCACHE\3WCACHE\2NCQ\1TCQ\n"); - printf("=================================================\n"); -} - -static char * -ata_raid_intel_type(int type) -{ - static char buffer[16]; - - switch (type) { - case INTEL_T_RAID0: return "RAID0"; - case INTEL_T_RAID1: return "RAID1"; - case INTEL_T_RAID5: return "RAID5"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_intel_print_meta(struct intel_raid_conf *meta) -{ - struct intel_raid_mapping *map; - int i, j; - - printf("********* ATA Intel MatrixRAID Metadata *********\n"); - printf("intel_id <%.24s>\n", meta->intel_id); - printf("version <%.6s>\n", meta->version); - printf("checksum 0x%08x\n", meta->checksum); - printf("config_size 0x%08x\n", meta->config_size); - printf("config_id 0x%08x\n", meta->config_id); - printf("generation 0x%08x\n", meta->generation); - printf("total_disks %u\n", meta->total_disks); - printf("total_volumes %u\n", meta->total_volumes); - printf("DISK# serial disk_sectors disk_id flags\n"); - for (i = 0; i < meta->total_disks; i++ ) { - printf(" %d <%.16s> %u 0x%08x 0x%08x\n", i, - meta->disk[i].serial, meta->disk[i].sectors, - meta->disk[i].id, meta->disk[i].flags); - } - map = (struct intel_raid_mapping *)&meta->disk[meta->total_disks]; - for (j = 0; j < meta->total_volumes; j++) { - printf("name %.16s\n", map->name); - printf("total_sectors %ju\n", map->total_sectors); - printf("state %u\n", map->state); - printf("reserved %u\n", map->reserved); - printf("offset %u\n", map->offset); - printf("disk_sectors %u\n", map->disk_sectors); - printf("stripe_count %u\n", map->stripe_count); - printf("stripe_sectors %u\n", map->stripe_sectors); - printf("status %u\n", map->status); - printf("type %s\n", ata_raid_intel_type(map->type)); - printf("total_disks %u\n", map->total_disks); - printf("magic[0] 0x%02x\n", map->magic[0]); - printf("magic[1] 0x%02x\n", map->magic[1]); - printf("magic[2] 0x%02x\n", map->magic[2]); - for (i = 0; i < map->total_disks; i++ ) { - printf(" disk %d at disk_idx 0x%08x\n", i, map->disk_idx[i]); - } - map = (struct intel_raid_mapping *)&map->disk_idx[map->total_disks]; - } - printf("=================================================\n"); -} - -static char * -ata_raid_ite_type(int type) -{ - static char buffer[16]; - - switch (type) { - case ITE_T_RAID0: return "RAID0"; - case ITE_T_RAID1: return "RAID1"; - case ITE_T_RAID01: return "RAID0+1"; - case ITE_T_SPAN: return "SPAN"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_ite_print_meta(struct ite_raid_conf *meta) -{ - printf("*** ATA Integrated Technology Express Metadata **\n"); - printf("ite_id <%.40s>\n", meta->ite_id); - printf("timestamp_0 %04x/%02x/%02x %02x:%02x:%02x.%02x\n", - *((u_int16_t *)meta->timestamp_0), meta->timestamp_0[2], - meta->timestamp_0[3], meta->timestamp_0[5], meta->timestamp_0[4], - meta->timestamp_0[7], meta->timestamp_0[6]); - printf("total_sectors %jd\n", meta->total_sectors); - printf("type %s\n", ata_raid_ite_type(meta->type)); - printf("stripe_1kblocks %u\n", meta->stripe_1kblocks); - printf("timestamp_1 %04x/%02x/%02x %02x:%02x:%02x.%02x\n", - *((u_int16_t *)meta->timestamp_1), meta->timestamp_1[2], - meta->timestamp_1[3], meta->timestamp_1[5], meta->timestamp_1[4], - meta->timestamp_1[7], meta->timestamp_1[6]); - printf("stripe_sectors %u\n", meta->stripe_sectors); - printf("array_width %u\n", meta->array_width); - printf("disk_number %u\n", meta->disk_number); - printf("disk_sectors %u\n", meta->disk_sectors); - printf("=================================================\n"); -} - -static char * -ata_raid_jmicron_type(int type) -{ - static char buffer[16]; - - switch (type) { - case JM_T_RAID0: return "RAID0"; - case JM_T_RAID1: return "RAID1"; - case JM_T_RAID01: return "RAID0+1"; - case JM_T_JBOD: return "JBOD"; - case JM_T_RAID5: return "RAID5"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_jmicron_print_meta(struct jmicron_raid_conf *meta) -{ - int i; - - printf("***** ATA JMicron Technology Corp Metadata ******\n"); - printf("signature %.2s\n", meta->signature); - printf("version 0x%04x\n", meta->version); - printf("checksum 0x%04x\n", meta->checksum); - printf("disk_id 0x%08x\n", meta->disk_id); - printf("offset 0x%08x\n", meta->offset); - printf("disk_sectors_low 0x%08x\n", meta->disk_sectors_low); - printf("disk_sectors_high 0x%08x\n", meta->disk_sectors_high); - printf("name %.16s\n", meta->name); - printf("type %s\n", ata_raid_jmicron_type(meta->type)); - printf("stripe_shift %d\n", meta->stripe_shift); - printf("flags 0x%04x\n", meta->flags); - printf("spare:\n"); - for (i=0; i < 2 && meta->spare[i]; i++) - printf(" %d 0x%08x\n", i, meta->spare[i]); - printf("disks:\n"); - for (i=0; i < 8 && meta->disks[i]; i++) - printf(" %d 0x%08x\n", i, meta->disks[i]); - printf("=================================================\n"); -} - -static char * -ata_raid_lsiv2_type(int type) -{ - static char buffer[16]; - - switch (type) { - case LSIV2_T_RAID0: return "RAID0"; - case LSIV2_T_RAID1: return "RAID1"; - case LSIV2_T_SPARE: return "SPARE"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_lsiv2_print_meta(struct lsiv2_raid_conf *meta) -{ - int i; - - printf("******* ATA LSILogic V2 MegaRAID Metadata *******\n"); - printf("lsi_id <%s>\n", meta->lsi_id); - printf("dummy_0 0x%02x\n", meta->dummy_0); - printf("flags 0x%02x\n", meta->flags); - printf("version 0x%04x\n", meta->version); - printf("config_entries 0x%02x\n", meta->config_entries); - printf("raid_count 0x%02x\n", meta->raid_count); - printf("total_disks 0x%02x\n", meta->total_disks); - printf("dummy_1 0x%02x\n", meta->dummy_1); - printf("dummy_2 0x%04x\n", meta->dummy_2); - for (i = 0; i < meta->config_entries; i++) { - printf(" type %s\n", - ata_raid_lsiv2_type(meta->configs[i].raid.type)); - printf(" dummy_0 %02x\n", meta->configs[i].raid.dummy_0); - printf(" stripe_sectors %u\n", - meta->configs[i].raid.stripe_sectors); - printf(" array_width %u\n", - meta->configs[i].raid.array_width); - printf(" disk_count %u\n", meta->configs[i].raid.disk_count); - printf(" config_offset %u\n", - meta->configs[i].raid.config_offset); - printf(" dummy_1 %u\n", meta->configs[i].raid.dummy_1); - printf(" flags %02x\n", meta->configs[i].raid.flags); - printf(" total_sectors %u\n", - meta->configs[i].raid.total_sectors); - } - printf("disk_number 0x%02x\n", meta->disk_number); - printf("raid_number 0x%02x\n", meta->raid_number); - printf("timestamp 0x%08x\n", meta->timestamp); - printf("=================================================\n"); -} - -static char * -ata_raid_lsiv3_type(int type) -{ - static char buffer[16]; - - switch (type) { - case LSIV3_T_RAID0: return "RAID0"; - case LSIV3_T_RAID1: return "RAID1"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_lsiv3_print_meta(struct lsiv3_raid_conf *meta) -{ - int i; - - printf("******* ATA LSILogic V3 MegaRAID Metadata *******\n"); - printf("lsi_id <%.6s>\n", meta->lsi_id); - printf("dummy_0 0x%04x\n", meta->dummy_0); - printf("version 0x%04x\n", meta->version); - printf("dummy_0 0x%04x\n", meta->dummy_1); - printf("RAID configs:\n"); - for (i = 0; i < 8; i++) { - if (meta->raid[i].total_disks) { - printf("%02d stripe_pages %u\n", i, - meta->raid[i].stripe_pages); - printf("%02d type %s\n", i, - ata_raid_lsiv3_type(meta->raid[i].type)); - printf("%02d total_disks %u\n", i, - meta->raid[i].total_disks); - printf("%02d array_width %u\n", i, - meta->raid[i].array_width); - printf("%02d sectors %u\n", i, meta->raid[i].sectors); - printf("%02d offset %u\n", i, meta->raid[i].offset); - printf("%02d device 0x%02x\n", i, - meta->raid[i].device); - } - } - printf("DISK configs:\n"); - for (i = 0; i < 6; i++) { - if (meta->disk[i].disk_sectors) { - printf("%02d disk_sectors %u\n", i, - meta->disk[i].disk_sectors); - printf("%02d flags 0x%02x\n", i, meta->disk[i].flags); - } - } - printf("device 0x%02x\n", meta->device); - printf("timestamp 0x%08x\n", meta->timestamp); - printf("checksum_1 0x%02x\n", meta->checksum_1); - printf("=================================================\n"); -} - -static char * -ata_raid_nvidia_type(int type) -{ - static char buffer[16]; - - switch (type) { - case NV_T_SPAN: return "SPAN"; - case NV_T_RAID0: return "RAID0"; - case NV_T_RAID1: return "RAID1"; - case NV_T_RAID3: return "RAID3"; - case NV_T_RAID5: return "RAID5"; - case NV_T_RAID01: return "RAID0+1"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_nvidia_print_meta(struct nvidia_raid_conf *meta) -{ - printf("******** ATA nVidia MediaShield Metadata ********\n"); - printf("nvidia_id <%.8s>\n", meta->nvidia_id); - printf("config_size %d\n", meta->config_size); - printf("checksum 0x%08x\n", meta->checksum); - printf("version 0x%04x\n", meta->version); - printf("disk_number %d\n", meta->disk_number); - printf("dummy_0 0x%02x\n", meta->dummy_0); - printf("total_sectors %d\n", meta->total_sectors); - printf("sectors_size %d\n", meta->sector_size); - printf("serial %.16s\n", meta->serial); - printf("revision %.4s\n", meta->revision); - printf("dummy_1 0x%08x\n", meta->dummy_1); - printf("magic_0 0x%08x\n", meta->magic_0); - printf("magic_1 0x%016jx\n", meta->magic_1); - printf("magic_2 0x%016jx\n", meta->magic_2); - printf("flags 0x%02x\n", meta->flags); - printf("array_width %d\n", meta->array_width); - printf("total_disks %d\n", meta->total_disks); - printf("dummy_2 0x%02x\n", meta->dummy_2); - printf("type %s\n", ata_raid_nvidia_type(meta->type)); - printf("dummy_3 0x%04x\n", meta->dummy_3); - printf("stripe_sectors %d\n", meta->stripe_sectors); - printf("stripe_bytes %d\n", meta->stripe_bytes); - printf("stripe_shift %d\n", meta->stripe_shift); - printf("stripe_mask 0x%08x\n", meta->stripe_mask); - printf("stripe_sizesectors %d\n", meta->stripe_sizesectors); - printf("stripe_sizebytes %d\n", meta->stripe_sizebytes); - printf("rebuild_lba %d\n", meta->rebuild_lba); - printf("dummy_4 0x%08x\n", meta->dummy_4); - printf("dummy_5 0x%08x\n", meta->dummy_5); - printf("status 0x%08x\n", meta->status); - printf("=================================================\n"); -} - -static char * -ata_raid_promise_type(int type) -{ - static char buffer[16]; - - switch (type) { - case PR_T_RAID0: return "RAID0"; - case PR_T_RAID1: return "RAID1"; - case PR_T_RAID3: return "RAID3"; - case PR_T_RAID5: return "RAID5"; - case PR_T_SPAN: return "SPAN"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_promise_print_meta(struct promise_raid_conf *meta) -{ - int i; - - printf("********* ATA Promise FastTrak Metadata *********\n"); - printf("promise_id <%s>\n", meta->promise_id); - printf("dummy_0 0x%08x\n", meta->dummy_0); - printf("magic_0 0x%016jx\n", meta->magic_0); - printf("magic_1 0x%04x\n", meta->magic_1); - printf("magic_2 0x%08x\n", meta->magic_2); - printf("integrity 0x%08x %b\n", meta->raid.integrity, - meta->raid.integrity, "\20\10VALID\n" ); - printf("flags 0x%02x %b\n", - meta->raid.flags, meta->raid.flags, - "\20\10READY\7DOWN\6REDIR\5DUPLICATE\4SPARE" - "\3ASSIGNED\2ONLINE\1VALID\n"); - printf("disk_number %d\n", meta->raid.disk_number); - printf("channel 0x%02x\n", meta->raid.channel); - printf("device 0x%02x\n", meta->raid.device); - printf("magic_0 0x%016jx\n", meta->raid.magic_0); - printf("disk_offset %u\n", meta->raid.disk_offset); - printf("disk_sectors %u\n", meta->raid.disk_sectors); - printf("rebuild_lba 0x%08x\n", meta->raid.rebuild_lba); - printf("generation 0x%04x\n", meta->raid.generation); - printf("status 0x%02x %b\n", - meta->raid.status, meta->raid.status, - "\20\6MARKED\5DEGRADED\4READY\3INITED\2ONLINE\1VALID\n"); - printf("type %s\n", ata_raid_promise_type(meta->raid.type)); - printf("total_disks %u\n", meta->raid.total_disks); - printf("stripe_shift %u\n", meta->raid.stripe_shift); - printf("array_width %u\n", meta->raid.array_width); - printf("array_number %u\n", meta->raid.array_number); - printf("total_sectors %u\n", meta->raid.total_sectors); - printf("cylinders %u\n", meta->raid.cylinders); - printf("heads %u\n", meta->raid.heads); - printf("sectors %u\n", meta->raid.sectors); - printf("magic_1 0x%016jx\n", meta->raid.magic_1); - printf("DISK# flags dummy_0 channel device magic_0\n"); - for (i = 0; i < 8; i++) { - printf(" %d %b 0x%02x 0x%02x 0x%02x ", - i, meta->raid.disk[i].flags, - "\20\10READY\7DOWN\6REDIR\5DUPLICATE\4SPARE" - "\3ASSIGNED\2ONLINE\1VALID\n", meta->raid.disk[i].dummy_0, - meta->raid.disk[i].channel, meta->raid.disk[i].device); - printf("0x%016jx\n", meta->raid.disk[i].magic_0); - } - printf("checksum 0x%08x\n", meta->checksum); - printf("=================================================\n"); -} - -static char * -ata_raid_sii_type(int type) -{ - static char buffer[16]; - - switch (type) { - case SII_T_RAID0: return "RAID0"; - case SII_T_RAID1: return "RAID1"; - case SII_T_RAID01: return "RAID0+1"; - case SII_T_SPARE: return "SPARE"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_sii_print_meta(struct sii_raid_conf *meta) -{ - printf("******* ATA Silicon Image Medley Metadata *******\n"); - printf("total_sectors %ju\n", meta->total_sectors); - printf("dummy_0 0x%04x\n", meta->dummy_0); - printf("dummy_1 0x%04x\n", meta->dummy_1); - printf("controller_pci_id 0x%08x\n", meta->controller_pci_id); - printf("version_minor 0x%04x\n", meta->version_minor); - printf("version_major 0x%04x\n", meta->version_major); - printf("timestamp 20%02x/%02x/%02x %02x:%02x:%02x\n", - meta->timestamp[5], meta->timestamp[4], meta->timestamp[3], - meta->timestamp[2], meta->timestamp[1], meta->timestamp[0]); - printf("stripe_sectors %u\n", meta->stripe_sectors); - printf("dummy_2 0x%04x\n", meta->dummy_2); - printf("disk_number %u\n", meta->disk_number); - printf("type %s\n", ata_raid_sii_type(meta->type)); - printf("raid0_disks %u\n", meta->raid0_disks); - printf("raid0_ident %u\n", meta->raid0_ident); - printf("raid1_disks %u\n", meta->raid1_disks); - printf("raid1_ident %u\n", meta->raid1_ident); - printf("rebuild_lba %ju\n", meta->rebuild_lba); - printf("generation 0x%08x\n", meta->generation); - printf("status 0x%02x %b\n", - meta->status, meta->status, - "\20\1READY\n"); - printf("base_raid1_position %02x\n", meta->base_raid1_position); - printf("base_raid0_position %02x\n", meta->base_raid0_position); - printf("position %02x\n", meta->position); - printf("dummy_3 %04x\n", meta->dummy_3); - printf("name <%.16s>\n", meta->name); - printf("checksum_0 0x%04x\n", meta->checksum_0); - printf("checksum_1 0x%04x\n", meta->checksum_1); - printf("=================================================\n"); -} - -static char * -ata_raid_sis_type(int type) -{ - static char buffer[16]; - - switch (type) { - case SIS_T_JBOD: return "JBOD"; - case SIS_T_RAID0: return "RAID0"; - case SIS_T_RAID1: return "RAID1"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_sis_print_meta(struct sis_raid_conf *meta) -{ - printf("**** ATA Silicon Integrated Systems Metadata ****\n"); - printf("magic 0x%04x\n", meta->magic); - printf("disks 0x%02x\n", meta->disks); - printf("type %s\n", - ata_raid_sis_type(meta->type_total_disks & SIS_T_MASK)); - printf("total_disks %u\n", meta->type_total_disks & SIS_D_MASK); - printf("dummy_0 0x%08x\n", meta->dummy_0); - printf("controller_pci_id 0x%08x\n", meta->controller_pci_id); - printf("stripe_sectors %u\n", meta->stripe_sectors); - printf("dummy_1 0x%04x\n", meta->dummy_1); - printf("timestamp 0x%08x\n", meta->timestamp); - printf("model %.40s\n", meta->model); - printf("disk_number %u\n", meta->disk_number); - printf("dummy_2 0x%02x 0x%02x 0x%02x\n", - meta->dummy_2[0], meta->dummy_2[1], meta->dummy_2[2]); - printf("=================================================\n"); -} - -static char * -ata_raid_via_type(int type) -{ - static char buffer[16]; - - switch (type) { - case VIA_T_RAID0: return "RAID0"; - case VIA_T_RAID1: return "RAID1"; - case VIA_T_RAID5: return "RAID5"; - case VIA_T_RAID01: return "RAID0+1"; - case VIA_T_SPAN: return "SPAN"; - default: sprintf(buffer, "UNKNOWN 0x%02x", type); - return buffer; - } -} - -static void -ata_raid_via_print_meta(struct via_raid_conf *meta) -{ - int i; - - printf("*************** ATA VIA Metadata ****************\n"); - printf("magic 0x%02x\n", meta->magic); - printf("dummy_0 0x%02x\n", meta->dummy_0); - printf("type %s\n", - ata_raid_via_type(meta->type & VIA_T_MASK)); - printf("bootable %d\n", meta->type & VIA_T_BOOTABLE); - printf("unknown %d\n", meta->type & VIA_T_UNKNOWN); - printf("disk_index 0x%02x\n", meta->disk_index); - printf("stripe_layout 0x%02x\n", meta->stripe_layout); - printf(" stripe_disks %d\n", meta->stripe_layout & VIA_L_DISKS); - printf(" stripe_sectors %d\n", - 0x08 << ((meta->stripe_layout & VIA_L_MASK) >> VIA_L_SHIFT)); - printf("disk_sectors %ju\n", meta->disk_sectors); - printf("disk_id 0x%08x\n", meta->disk_id); - printf("DISK# disk_id\n"); - for (i = 0; i < 8; i++) { - if (meta->disks[i]) - printf(" %d 0x%08x\n", i, meta->disks[i]); - } - printf("checksum 0x%02x\n", meta->checksum); - printf("=================================================\n"); -} diff --git a/sys/dev/ata/ata-raid.h b/sys/dev/ata/ata-raid.h deleted file mode 100644 index 61f8a6f..0000000 --- a/sys/dev/ata/ata-raid.h +++ /dev/null @@ -1,817 +0,0 @@ -/*- - * Copyright (c) 2000 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* misc defines */ -#define MAX_ARRAYS 16 -#define MAX_VOLUMES 4 -#define MAX_DISKS 16 -#define AR_PROXIMITY 2048 /* how many sectors is "close" */ - -#define ATA_MAGIC "FreeBSD ATA driver RAID " - -struct ata_raid_subdisk { - struct ar_softc *raid[MAX_VOLUMES]; - int disk_number[MAX_VOLUMES]; -}; - -/* ATA PseudoRAID Metadata */ -struct ar_softc { - int lun; - u_int8_t name[32]; - int volume; - u_int64_t magic_0; - u_int64_t magic_1; - int type; -#define AR_T_JBOD 0x0001 -#define AR_T_SPAN 0x0002 -#define AR_T_RAID0 0x0004 -#define AR_T_RAID1 0x0008 -#define AR_T_RAID01 0x0010 -#define AR_T_RAID3 0x0020 -#define AR_T_RAID4 0x0040 -#define AR_T_RAID5 0x0080 - - int status; -#define AR_S_READY 0x0001 -#define AR_S_DEGRADED 0x0002 -#define AR_S_REBUILDING 0x0004 - - int format; -#define AR_F_FREEBSD_RAID 0x0001 -#define AR_F_ADAPTEC_RAID 0x0002 -#define AR_F_HPTV2_RAID 0x0004 -#define AR_F_HPTV3_RAID 0x0008 -#define AR_F_INTEL_RAID 0x0010 -#define AR_F_ITE_RAID 0x0020 -#define AR_F_JMICRON_RAID 0x0040 -#define AR_F_LSIV2_RAID 0x0080 -#define AR_F_LSIV3_RAID 0x0100 -#define AR_F_NVIDIA_RAID 0x0200 -#define AR_F_PROMISE_RAID 0x0400 -#define AR_F_SII_RAID 0x0800 -#define AR_F_SIS_RAID 0x1000 -#define AR_F_VIA_RAID 0x2000 -#define AR_F_DDF_RAID 0x4000 -#define AR_F_FORMAT_MASK 0x7fff - - u_int generation; - u_int64_t total_sectors; - u_int64_t offset_sectors; /* offset from start of disk */ - u_int16_t heads; - u_int16_t sectors; - u_int32_t cylinders; - u_int width; /* array width in disks */ - u_int interleave; /* interleave in sectors */ - u_int total_disks; /* number of disks in this array */ - struct ar_disk { - device_t dev; - u_int8_t serial[16]; /* serial # of physical disk */ - u_int64_t sectors; /* useable sectors on this disk */ - off_t last_lba; /* last lba used (for performance) */ - u_int flags; -#define AR_DF_PRESENT 0x0001 /* this HW pos has a disk present */ -#define AR_DF_ASSIGNED 0x0002 /* this HW pos assigned to an array */ -#define AR_DF_SPARE 0x0004 /* this HW pos is a spare */ -#define AR_DF_ONLINE 0x0008 /* this HW pos is online and in use */ - - } disks[MAX_DISKS]; - int toggle; /* performance hack for RAID1's */ - u_int64_t rebuild_lba; /* rebuild progress indicator */ - struct mtx lock; /* metadata lock */ - struct disk *disk; /* disklabel/slice stuff */ - struct proc *pid; /* rebuilder process id */ -}; - -/* Adaptec HostRAID Metadata */ -#define ADP_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 17) - -/* note all entries are big endian */ -struct adaptec_raid_conf { - u_int32_t magic_0; -#define ADP_MAGIC_0 0xc4650790 - - u_int32_t generation; - u_int16_t dummy_0; - u_int16_t total_configs; - u_int16_t dummy_1; - u_int16_t checksum; - u_int32_t dummy_2; - u_int32_t dummy_3; - u_int32_t flags; - u_int32_t timestamp; - u_int32_t dummy_4[4]; - u_int32_t dummy_5[4]; - struct { - u_int16_t total_disks; - u_int16_t generation; - u_int32_t magic_0; - u_int8_t dummy_0; - u_int8_t type; -#define ADP_T_RAID0 0x00 -#define ADP_T_RAID1 0x01 - u_int8_t dummy_1; - u_int8_t flags; - - u_int8_t dummy_2; - u_int8_t dummy_3; - u_int8_t dummy_4; - u_int8_t dummy_5; - - u_int32_t disk_number; - u_int32_t dummy_6; - u_int32_t sectors; - u_int16_t stripe_shift; - u_int16_t dummy_7; - - u_int32_t dummy_8[4]; - u_int8_t name[16]; - } configs[127]; - u_int32_t dummy_6[13]; - u_int32_t magic_1; -#define ADP_MAGIC_1 0x9ff85009 - u_int32_t dummy_7[3]; - u_int32_t magic_2; - u_int32_t dummy_8[46]; - u_int32_t magic_3; -#define ADP_MAGIC_3 0x4d545044 - u_int32_t magic_4; -#define ADP_MAGIC_4 0x9ff85009 - u_int32_t dummy_9[62]; -} __packed; - -/* DDF Information. Metadata definitions are in another file */ -#define DDF_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 1) - -/* Highpoint V2 RocketRAID Metadata */ -#define HPTV2_LBA(dev) 9 - -struct hptv2_raid_conf { - int8_t filler1[32]; - u_int32_t magic; -#define HPTV2_MAGIC_OK 0x5a7816f0 -#define HPTV2_MAGIC_BAD 0x5a7816fd - - u_int32_t magic_0; - u_int32_t magic_1; - u_int32_t order; -#define HPTV2_O_RAID0 0x01 -#define HPTV2_O_RAID1 0x02 -#define HPTV2_O_OK 0x04 - - u_int8_t array_width; - u_int8_t stripe_shift; - u_int8_t type; -#define HPTV2_T_RAID0 0x00 -#define HPTV2_T_RAID1 0x01 -#define HPTV2_T_RAID01_RAID0 0x02 -#define HPTV2_T_SPAN 0x03 -#define HPTV2_T_RAID_3 0x04 -#define HPTV2_T_RAID_5 0x05 -#define HPTV2_T_JBOD 0x06 -#define HPTV2_T_RAID01_RAID1 0x07 - - u_int8_t disk_number; - u_int32_t total_sectors; - u_int32_t disk_mode; - u_int32_t boot_mode; - u_int8_t boot_disk; - u_int8_t boot_protect; - u_int8_t error_log_entries; - u_int8_t error_log_index; - struct { - u_int32_t timestamp; - u_int8_t reason; -#define HPTV2_R_REMOVED 0xfe -#define HPTV2_R_BROKEN 0xff - - u_int8_t disk; - u_int8_t status; - u_int8_t sectors; - u_int32_t lba; - } errorlog[32]; - int8_t filler2[16]; - u_int32_t rebuild_lba; - u_int8_t dummy_1; - u_int8_t name_1[15]; - u_int8_t dummy_2; - u_int8_t name_2[15]; - int8_t filler3[8]; -} __packed; - - -/* Highpoint V3 RocketRAID Metadata */ -#define HPTV3_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 11) - -struct hptv3_raid_conf { - u_int32_t magic; -#define HPTV3_MAGIC 0x5a7816f3 - - u_int32_t magic_0; - u_int8_t checksum_0; - u_int8_t mode; -#define HPTV3_BOOT_MARK 0x01 -#define HPTV3_USER_MODE 0x02 - - u_int8_t user_mode; - u_int8_t config_entries; - struct { - u_int32_t total_sectors; - u_int8_t type; -#define HPTV3_T_SPARE 0x00 -#define HPTV3_T_JBOD 0x03 -#define HPTV3_T_SPAN 0x04 -#define HPTV3_T_RAID0 0x05 -#define HPTV3_T_RAID1 0x06 -#define HPTV3_T_RAID3 0x07 -#define HPTV3_T_RAID5 0x08 - - u_int8_t total_disks; - u_int8_t disk_number; - u_int8_t stripe_shift; - u_int16_t status; -#define HPTV3_T_NEED_REBUILD 0x01 -#define HPTV3_T_RAID5_FLAG 0x02 - - u_int16_t critical_disks; - u_int32_t rebuild_lba; - } __packed configs[2]; - u_int8_t name[16]; - u_int32_t timestamp; - u_int8_t description[64]; - u_int8_t creator[16]; - u_int8_t checksum_1; - u_int8_t dummy_0; - u_int8_t dummy_1; - u_int8_t flags; -#define HPTV3_T_ENABLE_TCQ 0x01 -#define HPTV3_T_ENABLE_NCQ 0x02 -#define HPTV3_T_ENABLE_WCACHE 0x04 -#define HPTV3_T_ENABLE_RCACHE 0x08 - - struct { - u_int32_t total_sectors; - u_int32_t rebuild_lba; - } __packed configs_high[2]; - u_int32_t filler[87]; -} __packed; - - -/* Intel MatrixRAID Metadata */ -#define INTEL_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 3) - -struct intel_raid_conf { - u_int8_t intel_id[24]; -#define INTEL_MAGIC "Intel Raid ISM Cfg Sig. " - - u_int8_t version[6]; -#define INTEL_VERSION_1100 "1.1.00" -#define INTEL_VERSION_1201 "1.2.01" -#define INTEL_VERSION_1202 "1.2.02" - - u_int8_t dummy_0[2]; - u_int32_t checksum; - u_int32_t config_size; - u_int32_t config_id; - u_int32_t generation; - u_int32_t dummy_1[2]; - u_int8_t total_disks; - u_int8_t total_volumes; - u_int8_t dummy_2[2]; - u_int32_t filler_0[39]; - struct { - u_int8_t serial[16]; - u_int32_t sectors; - u_int32_t id; - u_int32_t flags; -#define INTEL_F_SPARE 0x01 -#define INTEL_F_ASSIGNED 0x02 -#define INTEL_F_DOWN 0x04 -#define INTEL_F_ONLINE 0x08 - - u_int32_t filler[5]; - } __packed disk[1]; - u_int32_t filler_1[62]; -} __packed; - -struct intel_raid_mapping { - u_int8_t name[16]; - u_int64_t total_sectors __packed; - u_int32_t state; - u_int32_t reserved; - u_int32_t filler_0[20]; - u_int32_t offset; - u_int32_t disk_sectors; - u_int32_t stripe_count; - u_int16_t stripe_sectors; - u_int8_t status; -#define INTEL_S_READY 0x00 -#define INTEL_S_DISABLED 0x01 -#define INTEL_S_DEGRADED 0x02 -#define INTEL_S_FAILURE 0x03 - - u_int8_t type; -#define INTEL_T_RAID0 0x00 -#define INTEL_T_RAID1 0x01 -#define INTEL_T_RAID5 0x05 - - u_int8_t total_disks; - u_int8_t magic[3]; - u_int32_t filler_1[7]; - u_int32_t disk_idx[1]; -} __packed; - - -/* Integrated Technology Express Metadata */ -#define ITE_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 2) - -struct ite_raid_conf { - u_int32_t filler_1[5]; - u_int8_t timestamp_0[8]; - u_int32_t dummy_1; - u_int32_t filler_2[5]; - u_int16_t filler_3; - u_int8_t ite_id[40]; -#define ITE_MAGIC "Integrated Technology Express Inc " - - u_int16_t filler_4; - u_int32_t filler_5[6]; - u_int32_t dummy_2; - u_int32_t dummy_3; - u_int32_t filler_6[12]; - u_int32_t dummy_4; - u_int32_t filler_7[5]; - u_int64_t total_sectors __packed; - u_int32_t filler_8[12]; - - u_int16_t filler_9; - u_int8_t type; -#define ITE_T_RAID0 0x00 -#define ITE_T_RAID1 0x01 -#define ITE_T_RAID01 0x02 -#define ITE_T_SPAN 0x03 - - u_int8_t filler_10; - u_int32_t dummy_5[8]; - u_int8_t stripe_1kblocks; - u_int8_t filler_11[3]; - u_int32_t filler_12[54]; - - u_int32_t dummy_6[4]; - u_int8_t timestamp_1[8]; - u_int32_t filler_13[9]; - u_int8_t stripe_sectors; - u_int8_t filler_14[3]; - u_int8_t array_width; - u_int8_t filler_15[3]; - u_int32_t filler_16; - u_int8_t filler_17; - u_int8_t disk_number; - u_int32_t disk_sectors; - u_int16_t filler_18; - u_int32_t dummy_7[4]; - u_int32_t filler_20[104]; -} __packed; - - -/* JMicron Technology Corp Metadata */ -#define JMICRON_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 1) -#define JM_MAX_DISKS 8 - -struct jmicron_raid_conf { - u_int8_t signature[2]; -#define JMICRON_MAGIC "JM" - - u_int16_t version; -#define JMICRON_VERSION 0x0001 - - u_int16_t checksum; - u_int8_t filler_1[10]; - u_int32_t disk_id; - u_int32_t offset; - u_int32_t disk_sectors_high; - u_int16_t disk_sectors_low; - u_int8_t filler_2[2]; - u_int8_t name[16]; - u_int8_t type; -#define JM_T_RAID0 0 -#define JM_T_RAID1 1 -#define JM_T_RAID01 2 -#define JM_T_JBOD 3 -#define JM_T_RAID5 5 - - u_int8_t stripe_shift; - u_int16_t flags; -#define JM_F_READY 0x0001 -#define JM_F_BOOTABLE 0x0002 -#define JM_F_BAD 0x0004 -#define JM_F_ACTIVE 0c0010 -#define JM_F_UNSYNC 0c0020 -#define JM_F_NEWEST 0c0040 - - u_int8_t filler_3[4]; - u_int32_t spare[2]; - u_int32_t disks[JM_MAX_DISKS]; - u_int8_t filler_4[32]; - u_int8_t filler_5[384]; -}; - - -/* LSILogic V2 MegaRAID Metadata */ -#define LSIV2_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 1) - -struct lsiv2_raid_conf { - u_int8_t lsi_id[6]; -#define LSIV2_MAGIC "$XIDE$" - - u_int8_t dummy_0; - u_int8_t flags; - u_int16_t version; - u_int8_t config_entries; - u_int8_t raid_count; - u_int8_t total_disks; - u_int8_t dummy_1; - u_int16_t dummy_2; - - union { - struct { - u_int8_t type; -#define LSIV2_T_RAID0 0x01 -#define LSIV2_T_RAID1 0x02 -#define LSIV2_T_SPARE 0x08 - - u_int8_t dummy_0; - u_int16_t stripe_sectors; - u_int8_t array_width; - u_int8_t disk_count; - u_int8_t config_offset; - u_int8_t dummy_1; - u_int8_t flags; -#define LSIV2_R_DEGRADED 0x02 - - u_int32_t total_sectors; - u_int8_t filler[3]; - } __packed raid; - struct { - u_int8_t device; -#define LSIV2_D_MASTER 0x00 -#define LSIV2_D_SLAVE 0x01 -#define LSIV2_D_CHANNEL0 0x00 -#define LSIV2_D_CHANNEL1 0x10 -#define LSIV2_D_NONE 0xff - - u_int8_t dummy_0; - u_int32_t disk_sectors; - u_int8_t disk_number; - u_int8_t raid_number; - u_int8_t flags; -#define LSIV2_D_GONE 0x02 - - u_int8_t filler[7]; - } __packed disk; - } configs[30]; - u_int8_t disk_number; - u_int8_t raid_number; - u_int32_t timestamp; - u_int8_t filler[10]; -} __packed; - - -/* LSILogic V3 MegaRAID Metadata */ -#define LSIV3_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 4) - -struct lsiv3_raid_conf { - u_int32_t magic_0; /* 0xa0203200 */ - u_int32_t filler_0[3]; - u_int8_t magic_1[4]; /* "SATA" */ - u_int32_t filler_1[40]; - u_int32_t dummy_0; /* 0x0d000003 */ - u_int32_t filler_2[7]; - u_int32_t dummy_1; /* 0x0d000003 */ - u_int32_t filler_3[70]; - u_int8_t magic_2[8]; /* "$_ENQ$31" */ - u_int8_t filler_4[7]; - u_int8_t checksum_0; - u_int8_t filler_5[512*2]; - u_int8_t lsi_id[6]; -#define LSIV3_MAGIC "$_IDE$" - - u_int16_t dummy_2; /* 0x33de for OK disk */ - u_int16_t version; /* 0x0131 for this version */ - u_int16_t dummy_3; /* 0x0440 always */ - u_int32_t filler_6; - - struct { - u_int16_t stripe_pages; - u_int8_t type; -#define LSIV3_T_RAID0 0x00 -#define LSIV3_T_RAID1 0x01 - - u_int8_t dummy_0; - u_int8_t total_disks; - u_int8_t array_width; - u_int8_t filler_0[10]; - - u_int32_t sectors; - u_int16_t dummy_1; - u_int32_t offset; - u_int16_t dummy_2; - u_int8_t device; -#define LSIV3_D_DEVICE 0x01 -#define LSIV3_D_CHANNEL 0x10 - - u_int8_t dummy_3; - u_int8_t dummy_4; - u_int8_t dummy_5; - u_int8_t filler_1[16]; - } __packed raid[8]; - struct { - u_int32_t disk_sectors; - u_int32_t dummy_0; - u_int32_t dummy_1; - u_int8_t dummy_2; - u_int8_t dummy_3; - u_int8_t flags; -#define LSIV3_D_MIRROR 0x00 -#define LSIV3_D_STRIPE 0xff - u_int8_t dummy_4; - } __packed disk[6]; - u_int8_t filler_7[7]; - u_int8_t device; - u_int32_t timestamp; - u_int8_t filler_8[3]; - u_int8_t checksum_1; -} __packed; - - -/* nVidia MediaShield Metadata */ -#define NVIDIA_LBA(dev) \ - (((struct ad_softc *)device_get_ivars(dev))->total_secs - 2) - -struct nvidia_raid_conf { - u_int8_t nvidia_id[8]; -#define NV_MAGIC "NVIDIA " - - u_int32_t config_size; - u_int32_t checksum; - u_int16_t version; - u_int8_t disk_number; - u_int8_t dummy_0; - u_int32_t total_sectors; - u_int32_t sector_size; - u_int8_t serial[16]; - u_int8_t revision[4]; - u_int32_t dummy_1; - - u_int32_t magic_0; -#define NV_MAGIC0 0x00640044 - - u_int64_t magic_1; - u_int64_t magic_2; - u_int8_t flags; - u_int8_t array_width; - u_int8_t total_disks; - u_int8_t dummy_2; - u_int16_t type; -#define NV_T_RAID0 0x00000080 -#define NV_T_RAID1 0x00000081 -#define NV_T_RAID3 0x00000083 -#define NV_T_RAID5 0x00000085 -#define NV_T_RAID01 0x00008180 -#define NV_T_SPAN 0x000000ff - - u_int16_t dummy_3; - u_int32_t stripe_sectors; - u_int32_t stripe_bytes; - u_int32_t stripe_shift; - u_int32_t stripe_mask; - u_int32_t stripe_sizesectors; - u_int32_t stripe_sizebytes; - u_int32_t rebuild_lba; - u_int32_t dummy_4; - u_int32_t dummy_5; - u_int32_t status; -#define NV_S_BOOTABLE 0x00000001 -#define NV_S_DEGRADED 0x00000002 - - u_int32_t filler[98]; -} __packed; - - -/* Promise FastTrak Metadata */ -#define PROMISE_LBA(dev) \ - (((((struct ad_softc *)device_get_ivars(dev))->total_secs / (((struct ad_softc *)device_get_ivars(dev))->heads * ((struct ad_softc *)device_get_ivars(dev))->sectors)) * ((struct ad_softc *)device_get_ivars(dev))->heads * ((struct ad_softc *)device_get_ivars(dev))->sectors) - ((struct ad_softc *)device_get_ivars(dev))->sectors) - -struct promise_raid_conf { - char promise_id[24]; -#define PR_MAGIC "Promise Technology, Inc." - - u_int32_t dummy_0; - u_int64_t magic_0; -#define PR_MAGIC0(x) (((u_int64_t)(x.channel) << 48) | \ - ((u_int64_t)(x.device != 0) << 56)) - u_int16_t magic_1; - u_int32_t magic_2; - u_int8_t filler1[470]; - struct { - u_int32_t integrity; -#define PR_I_VALID 0x00000080 - - u_int8_t flags; -#define PR_F_VALID 0x00000001 -#define PR_F_ONLINE 0x00000002 -#define PR_F_ASSIGNED 0x00000004 -#define PR_F_SPARE 0x00000008 -#define PR_F_DUPLICATE 0x00000010 -#define PR_F_REDIR 0x00000020 -#define PR_F_DOWN 0x00000040 -#define PR_F_READY 0x00000080 - - u_int8_t disk_number; - u_int8_t channel; - u_int8_t device; - u_int64_t magic_0 __packed; - u_int32_t disk_offset; - u_int32_t disk_sectors; - u_int32_t rebuild_lba; - u_int16_t generation; - u_int8_t status; -#define PR_S_VALID 0x01 -#define PR_S_ONLINE 0x02 -#define PR_S_INITED 0x04 -#define PR_S_READY 0x08 -#define PR_S_DEGRADED 0x10 -#define PR_S_MARKED 0x20 -#define PR_S_FUNCTIONAL 0x80 - - u_int8_t type; -#define PR_T_RAID0 0x00 -#define PR_T_RAID1 0x01 -#define PR_T_RAID3 0x02 -#define PR_T_RAID5 0x04 -#define PR_T_SPAN 0x08 -#define PR_T_JBOD 0x10 - - u_int8_t total_disks; - u_int8_t stripe_shift; - u_int8_t array_width; - u_int8_t array_number; - u_int32_t total_sectors; - u_int16_t cylinders; - u_int8_t heads; - u_int8_t sectors; - u_int64_t magic_1 __packed; - struct { - u_int8_t flags; - u_int8_t dummy_0; - u_int8_t channel; - u_int8_t device; - u_int64_t magic_0 __packed; - } disk[8]; - } raid; - int32_t filler2[346]; - u_int32_t checksum; -} __packed; - - -/* Silicon Image Medley Metadata */ -#define SII_LBA(dev) \ - ( ((struct ad_softc *)device_get_ivars(dev))->total_secs - 1) - -struct sii_raid_conf { - u_int16_t ata_params_00_53[54]; - u_int64_t total_sectors; - u_int16_t ata_params_58_79[70]; - u_int16_t dummy_0; - u_int16_t dummy_1; - u_int32_t controller_pci_id; - u_int16_t version_minor; - u_int16_t version_major; - u_int8_t timestamp[6]; - u_int16_t stripe_sectors; - u_int16_t dummy_2; - u_int8_t disk_number; - u_int8_t type; -#define SII_T_RAID0 0x00 -#define SII_T_RAID1 0x01 -#define SII_T_RAID01 0x02 -#define SII_T_SPARE 0x03 - - u_int8_t raid0_disks; - u_int8_t raid0_ident; - u_int8_t raid1_disks; - u_int8_t raid1_ident; - u_int64_t rebuild_lba; - u_int32_t generation; - u_int8_t status; -#define SII_S_READY 0x01 - - u_int8_t base_raid1_position; - u_int8_t base_raid0_position; - u_int8_t position; - u_int16_t dummy_3; - u_int8_t name[16]; - u_int16_t checksum_0; - int8_t filler1[190]; - u_int16_t checksum_1; -} __packed; - - -/* Silicon Integrated Systems RAID Metadata */ -#define SIS_LBA(dev) \ - ( ((struct ad_softc *)device_get_ivars(dev))->total_secs - 16) - -struct sis_raid_conf { - u_int16_t magic; -#define SIS_MAGIC 0x0010 - - u_int8_t disks; -#define SIS_D_MASTER 0xf0 -#define SIS_D_MIRROR 0x0f - - u_int8_t type_total_disks; -#define SIS_D_MASK 0x0f -#define SIS_T_MASK 0xf0 -#define SIS_T_JBOD 0x10 -#define SIS_T_RAID0 0x20 -#define SIS_T_RAID1 0x30 - - u_int32_t dummy_0; - u_int32_t controller_pci_id; - u_int16_t stripe_sectors; - u_int16_t dummy_1; - u_int32_t timestamp; - u_int8_t model[40]; - u_int8_t disk_number; - u_int8_t dummy_2[3]; - int8_t filler1[448]; -} __packed; - - -/* VIA Tech V-RAID Metadata */ -#define VIA_LBA(dev) \ - ( ((struct ad_softc *)device_get_ivars(dev))->total_secs - 1) - -struct via_raid_conf { - u_int16_t magic; -#define VIA_MAGIC 0xaa55 - - u_int8_t dummy_0; - u_int8_t type; -#define VIA_T_MASK 0x7e -#define VIA_T_BOOTABLE 0x01 -#define VIA_T_RAID0 0x04 -#define VIA_T_RAID1 0x0c -#define VIA_T_RAID01 0x4c -#define VIA_T_RAID5 0x2c -#define VIA_T_SPAN 0x44 -#define VIA_T_UNKNOWN 0x80 - - u_int8_t disk_index; -#define VIA_D_MASK 0x0f -#define VIA_D_DEGRADED 0x10 -#define VIA_D_HIGH_IDX 0x20 - - u_int8_t stripe_layout; -#define VIA_L_DISKS 0x07 -#define VIA_L_MASK 0xf0 -#define VIA_L_SHIFT 4 - - u_int64_t disk_sectors; - u_int32_t disk_id; - u_int32_t disks[8]; - u_int8_t checksum; - u_int8_t filler_1[461]; -} __packed; diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c index 2a85d38..b219e07 100644 --- a/sys/dev/ata/ata-sata.c +++ b/sys/dev/ata/ata-sata.c @@ -157,13 +157,9 @@ ata_sata_phy_reset(device_t dev, int port, int quick) int loop, retry, sata_rev; uint32_t val, val1; -#ifdef ATA_CAM sata_rev = ch->user[port < 0 ? 0 : port].revision; if (sata_rev > 0) quick = 0; -#else - sata_rev = 0; -#endif if (quick) { if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val)) diff --git a/sys/dev/ata/ata_if.m b/sys/dev/ata/ata_if.m index 5894c8c..821f5b2 100644 --- a/sys/dev/ata/ata_if.m +++ b/sys/dev/ata/ata_if.m @@ -39,24 +39,6 @@ INTERFACE ata; CODE { - static int ata_null_locking(device_t dev, int mode) - { - struct ata_channel *ch = device_get_softc(dev); - - return ch->unit; - } -}; -METHOD int locking { - device_t channel; - int mode; -} DEFAULT ata_null_locking; -HEADER { -#define ATA_LF_LOCK 0x0001 -#define ATA_LF_UNLOCK 0x0002 -#define ATA_LF_WHICH 0x0004 -}; - -CODE { static int ata_null_setmode(device_t dev, int target, int mode) { diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c deleted file mode 100644 index 0181785..0000000 --- a/sys/dev/ata/atapi-cam.c +++ /dev/null @@ -1,919 +0,0 @@ -/*- - * Copyright (c) 2001-2007 Thomas Quinot - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* private data associated with an ATA bus */ -struct atapi_xpt_softc { - struct ata_device atapi_cam_dev; /* must be first */ - device_t dev; - device_t parent; - struct ata_channel *ata_ch; - struct cam_path *path; - struct cam_sim *sim; - int flags; -#define BUS_REGISTERED 0x01 -#define RESOURCE_SHORTAGE 0x02 -#define DETACHING 0x04 - - TAILQ_HEAD(,atapi_hcb) pending_hcbs; - struct ata_device *atadev[2]; - struct mtx state_lock; -}; - -/* hardware command descriptor block */ -struct atapi_hcb { - struct atapi_xpt_softc *softc; - int unit; - int bus; - int target; - int lun; - union ccb *ccb; - int flags; -#define QUEUED 0x0001 -#define AUTOSENSE 0x0002 - char *dxfer_alloc; - TAILQ_ENTRY(atapi_hcb) chain; -}; - -enum reinit_reason { BOOT_ATTACH, ATTACH, RESET }; - -/* Device methods */ -static void atapi_cam_identify(driver_t *dev, device_t parent); -static int atapi_cam_probe(device_t dev); -static int atapi_cam_attach(device_t dev); -static int atapi_cam_detach(device_t dev); -static int atapi_cam_reinit(device_t dev); - -/* CAM XPT methods */ -static void atapi_action(struct cam_sim *, union ccb *); -static void atapi_poll(struct cam_sim *); -static void atapi_async(void *, u_int32_t, struct cam_path *, void *); -static void atapi_cb(struct ata_request *); - -/* Module methods */ -static int atapi_cam_event_handler(module_t mod, int what, void *arg); - -/* internal functions */ -static void reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason); -static void setup_async_cb(struct atapi_xpt_softc *, uint32_t); -static void cam_rescan(struct cam_sim *); -static void free_hcb_and_ccb_done(struct atapi_hcb *, u_int32_t); -static struct atapi_hcb *allocate_hcb(struct atapi_xpt_softc *, int, int, union ccb *); -static void free_hcb(struct atapi_hcb *hcb); -static void free_softc(struct atapi_xpt_softc *scp); - -static MALLOC_DEFINE(M_ATACAM, "ata_cam", "ATA driver CAM-XPT layer"); - -static device_method_t atapi_cam_methods[] = { - DEVMETHOD(device_identify, atapi_cam_identify), - DEVMETHOD(device_probe, atapi_cam_probe), - DEVMETHOD(device_attach, atapi_cam_attach), - DEVMETHOD(device_detach, atapi_cam_detach), - DEVMETHOD(ata_reinit, atapi_cam_reinit), - DEVMETHOD_END -}; - -static driver_t atapi_cam_driver = { - "atapicam", - atapi_cam_methods, - sizeof(struct atapi_xpt_softc) -}; - -static devclass_t atapi_cam_devclass; -DRIVER_MODULE(atapicam, ata, - atapi_cam_driver, - atapi_cam_devclass, - atapi_cam_event_handler, - /*arg*/NULL); -MODULE_VERSION(atapicam, 1); -MODULE_DEPEND(atapicam, ata, 1, 1, 1); -MODULE_DEPEND(atapicam, cam, 1, 1, 1); - -static void -atapi_cam_identify(driver_t *driver, device_t parent) -{ - struct atapi_xpt_softc *scp = - malloc (sizeof (struct atapi_xpt_softc), M_ATACAM, M_NOWAIT|M_ZERO); - device_t child; - - if (scp == NULL) { - printf ("atapi_cam_identify: out of memory"); - return; - } - - /* Assume one atapicam instance per parent channel instance. */ - child = device_add_child(parent, "atapicam", -1); - if (child == NULL) { - printf ("atapi_cam_identify: out of memory, can't add child"); - free (scp, M_ATACAM); - return; - } - scp->atapi_cam_dev.unit = -1; - scp->atapi_cam_dev.dev = child; - device_quiet(child); - device_set_softc(child, scp); -} - -static int -atapi_cam_probe(device_t dev) -{ - struct ata_device *atadev = device_get_softc (dev); - - KASSERT(atadev != NULL, ("expect valid struct ata_device")); - if (atadev->unit < 0) { - device_set_desc(dev, "ATAPI CAM Attachment"); - return (0); - } else { - return ENXIO; - } -} - -static int -atapi_cam_attach(device_t dev) -{ - struct atapi_xpt_softc *scp = NULL; - struct cam_devq *devq = NULL; - struct cam_sim *sim = NULL; - struct cam_path *path = NULL; - int unit, error; - - scp = (struct atapi_xpt_softc *)device_get_softc(dev); - if (scp == NULL) { - device_printf(dev, "Cannot get softc\n"); - return (ENOMEM); - } - - mtx_init(&scp->state_lock, "ATAPICAM lock", NULL, MTX_DEF); - - scp->dev = dev; - scp->parent = device_get_parent(dev); - scp->ata_ch = device_get_softc(scp->parent); - TAILQ_INIT(&scp->pending_hcbs); - unit = device_get_unit(device_get_parent(dev)); - - if ((devq = cam_simq_alloc(16)) == NULL) { - error = ENOMEM; - goto out; - } - - if ((sim = cam_sim_alloc(atapi_action, atapi_poll, "ata", - (void *)scp, unit, &scp->state_lock, 1, 1, devq)) == NULL) { - error = ENOMEM; - goto out; - } - scp->sim = sim; - - mtx_lock(&scp->state_lock); - if (xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) { - error = EINVAL; - mtx_unlock(&scp->state_lock); - goto out; - } - scp->flags |= BUS_REGISTERED; - - if (xpt_create_path(&path, /*periph*/ NULL, - cam_sim_path(sim), CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - error = ENOMEM; - mtx_unlock(&scp->state_lock); - goto out; - } - scp->path = path; - - CAM_DEBUG(path, CAM_DEBUG_TRACE, ("Registered SIM for ata%d\n", unit)); - - setup_async_cb(scp, AC_LOST_DEVICE); - reinit_bus(scp, cold ? BOOT_ATTACH : ATTACH); - error = 0; - mtx_unlock(&scp->state_lock); - -out: - if (error != 0) - free_softc(scp); - - return (error); -} - -static int -atapi_cam_detach(device_t dev) -{ - struct atapi_xpt_softc *scp = device_get_softc(dev); - - mtx_lock(&scp->state_lock); - if (xpt_sim_opened(scp->sim)) { - mtx_unlock(&scp->state_lock); - return (EBUSY); - } - xpt_freeze_simq(scp->sim, 1 /*count*/); - scp->flags |= DETACHING; - mtx_unlock(&scp->state_lock); - free_softc(scp); - return (0); -} - -static int -atapi_cam_reinit(device_t dev) { - struct atapi_xpt_softc *scp = device_get_softc(dev); - - /* - * scp might be null if the bus is being reinitialised during - * the boot-up sequence, before the ATAPI bus is registered. - */ - - if (scp != NULL) { - mtx_lock(&scp->state_lock); - reinit_bus(scp, RESET); - mtx_unlock(&scp->state_lock); - } - return (0); -} - -static void -reinit_bus(struct atapi_xpt_softc *scp, enum reinit_reason reason) { - struct ata_device *old_atadev[2], *atadev; - device_t *children; - int nchildren, i, dev_changed; - - if (device_get_children(scp->parent, &children, &nchildren) != 0) { - return; - } - - old_atadev[0] = scp->atadev[0]; - old_atadev[1] = scp->atadev[1]; - scp->atadev[0] = NULL; - scp->atadev[1] = NULL; - - for (i = 0; i < nchildren; i++) { - /* XXX Does the child need to actually be attached yet? */ - if (children[i] != NULL) { - atadev = device_get_softc(children[i]); - if ((atadev->unit == ATA_MASTER) && - (scp->ata_ch->devices & ATA_ATAPI_MASTER) != 0) - scp->atadev[0] = atadev; - if ((atadev->unit == ATA_SLAVE) && - (scp->ata_ch->devices & ATA_ATAPI_SLAVE) != 0) - scp->atadev[1] = atadev; - } - } - dev_changed = (old_atadev[0] != scp->atadev[0]) - || (old_atadev[1] != scp->atadev[1]); - free(children, M_TEMP); - - switch (reason) { - case BOOT_ATTACH: - case ATTACH: - break; - case RESET: - xpt_async(AC_BUS_RESET, scp->path, NULL); - - if (!dev_changed) - break; - - cam_rescan(scp->sim); - break; - } -} - -static void -setup_async_cb(struct atapi_xpt_softc *scp, uint32_t events) -{ - struct ccb_setasync csa; - - xpt_setup_ccb(&csa.ccb_h, scp->path, /*priority*/ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = events; - csa.callback = &atapi_async; - csa.callback_arg = scp->sim; - xpt_action((union ccb *) &csa); -} - -static void -atapi_action(struct cam_sim *sim, union ccb *ccb) -{ - struct atapi_xpt_softc *softc = (struct atapi_xpt_softc*)cam_sim_softc(sim); - struct ccb_hdr *ccb_h = &ccb->ccb_h; - struct atapi_hcb *hcb = NULL; - struct ata_request *request = NULL; - int unit = cam_sim_unit(sim); - int bus = cam_sim_bus(sim); - int len; - char *buf; - - switch (ccb_h->func_code) { - case XPT_PATH_INQ: { - struct ccb_pathinq *cpi = &ccb->cpi; - int tid = ccb_h->target_id; - - cpi->version_num = 1; - cpi->hba_inquiry = 0; - cpi->target_sprt = 0; - cpi->hba_misc = PIM_NO_6_BYTE; - cpi->hba_eng_cnt = 0; - bzero(cpi->vuhba_flags, sizeof(cpi->vuhba_flags)); - cpi->max_target = 1; - cpi->max_lun = 0; - cpi->async_flags = 0; - cpi->hpath_id = 0; - cpi->initiator_id = 7; - strncpy(cpi->sim_vid, "FreeBSD", sizeof(cpi->sim_vid)); - strncpy(cpi->hba_vid, "ATAPI", sizeof(cpi->hba_vid)); - strncpy(cpi->dev_name, cam_sim_name(sim), sizeof cpi->dev_name); - cpi->unit_number = cam_sim_unit(sim); - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - cpi->transport = XPORT_SPI; - cpi->transport_version = 2; - cpi->protocol = PROTO_SCSI; - cpi->protocol_version = SCSI_REV_2; - - if (softc->ata_ch && tid != CAM_TARGET_WILDCARD) { - if (softc->atadev[tid] == NULL) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; - xpt_done(ccb); - return; - } - switch (softc->atadev[ccb_h->target_id]->mode) { - case ATA_PIO1: - cpi->base_transfer_speed = 5200; - break; - case ATA_PIO2: - cpi->base_transfer_speed = 7000; - break; - case ATA_PIO3: - cpi->base_transfer_speed = 11000; - break; - case ATA_PIO4: - case ATA_DMA: - case ATA_WDMA2: - cpi->base_transfer_speed = 16000; - break; - case ATA_UDMA2: - cpi->base_transfer_speed = 33000; - break; - case ATA_UDMA4: - cpi->base_transfer_speed = 66000; - break; - case ATA_UDMA5: - cpi->base_transfer_speed = 100000; - break; - case ATA_UDMA6: - cpi->base_transfer_speed = 133000; - break; - case ATA_SA150: - cpi->base_transfer_speed = 150000; - break; - case ATA_SA300: - cpi->base_transfer_speed = 300000; - break; - default: - break; - } - } - cpi->maxio = softc->ata_ch->dma.max_iosize ? - softc->ata_ch->dma.max_iosize : DFLTPHYS; - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - return; - } - - case XPT_RESET_DEV: { - int tid = ccb_h->target_id; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("dev reset\n")); - mtx_unlock(&softc->state_lock); - ata_controlcmd(softc->atadev[tid]->dev, ATA_DEVICE_RESET, 0, 0, 0); - mtx_lock(&softc->state_lock); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - return; - } - - case XPT_RESET_BUS: - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("bus reset\n")); - mtx_unlock(&softc->state_lock); - ata_reinit(softc->parent); - mtx_lock(&softc->state_lock); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - return; - - case XPT_SET_TRAN_SETTINGS: - /* ignore these, we're not doing SCSI here */ - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, - ("SET_TRAN_SETTINGS not supported\n")); - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - xpt_done(ccb); - return; - - case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts = &ccb->cts; - cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_2; - cts->transport = XPORT_SPI; - cts->transport_version = XPORT_VERSION_UNSPECIFIED; - cts->proto_specific.valid = 0; - cts->xport_specific.valid = 0; - /* nothing more to do */ - ccb->ccb_h.status = CAM_REQ_CMP; - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("GET_TRAN_SETTINGS\n")); - xpt_done(ccb); - return; - } - - case XPT_CALC_GEOMETRY: { - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("CALC_GEOMETRY\n")); - cam_calc_geometry(&ccb->ccg, /*extended*/1); - xpt_done(ccb); - return; - } - - case XPT_SCSI_IO: { - struct ccb_scsiio *csio = &ccb->csio; - int tid = ccb_h->target_id, lid = ccb_h->target_lun; - int request_flags = ATA_R_ATAPI; - - CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, ("XPT_SCSI_IO\n")); - - if (softc->flags & DETACHING) { - ccb->ccb_h.status = CAM_REQ_ABORTED; - xpt_done(ccb); - return; - } - - if (softc->atadev[tid] == NULL) { - ccb->ccb_h.status = CAM_DEV_NOT_THERE; - xpt_done(ccb); - return; - } - - /* check that this request was not aborted already */ - if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { - printf("XPT_SCSI_IO received but already in progress?\n"); - xpt_done(ccb); - return; - } - if (lid > 0) { - CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, - ("SCSI IO received for invalid lun %d\n", lid)); - goto action_invalid; - } - if (csio->cdb_len > sizeof request->u.atapi.ccb) { - CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, - ("CAM CCB too long for ATAPI")); - goto action_invalid; - } - - switch (ccb_h->flags & CAM_DIR_MASK) { - case CAM_DIR_IN: - request_flags |= ATA_R_READ; - break; - case CAM_DIR_OUT: - request_flags |= ATA_R_WRITE; - break; - case CAM_DIR_NONE: - /* No flags need to be set */ - break; - default: - device_printf(softc->dev, "unknown IO operation\n"); - goto action_invalid; - } - - if ((hcb = allocate_hcb(softc, unit, bus, ccb)) == NULL) { - printf("cannot allocate ATAPI/CAM hcb\n"); - goto action_oom; - } - if ((request = ata_alloc_request()) == NULL) { - printf("cannot allocate ATAPI/CAM request\n"); - goto action_oom; - } - - bcopy((ccb_h->flags & CAM_CDB_POINTER) ? - csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes, - request->u.atapi.ccb, csio->cdb_len); -#ifdef CAMDEBUG - if (CAM_DEBUGGED(ccb_h->path, CAM_DEBUG_CDB)) { - char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; - - printf("atapi_action: hcb@%p: %s\n", hcb, - scsi_cdb_string(request->u.atapi.ccb, cdb_str, sizeof(cdb_str))); - } - if (CAM_DEBUGGED(ccb_h->path, CAM_DEBUG_SUBTRACE)) { - request_flags |= ATA_R_DEBUG; - } -#endif - - len = csio->dxfer_len; - buf = csio->data_ptr; - - /* some SCSI commands require special processing */ - switch (request->u.atapi.ccb[0]) { - case INQUIRY: { - /* - * many ATAPI devices seem to report more than - * SHORT_INQUIRY_LENGTH bytes of available INQUIRY - * information, but respond with some incorrect condition - * when actually asked for it, so we are going to pretend - * that only SHORT_INQUIRY_LENGTH are expected, anyway. - */ - struct scsi_inquiry *inq = (struct scsi_inquiry *) &request->u.atapi.ccb[0]; - - if (inq->byte2 == 0 && inq->page_code == 0 && - scsi_2btoul(inq->length) > SHORT_INQUIRY_LENGTH) { - bzero(buf, len); - len = SHORT_INQUIRY_LENGTH; - scsi_ulto2b(len, inq->length); - } - break; - } - case READ_6: - /* FALLTHROUGH */ - - case WRITE_6: - CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, - ("Translating %s into _10 equivalent\n", - (request->u.atapi.ccb[0] == READ_6) ? "READ_6" : "WRITE_6")); - request->u.atapi.ccb[0] |= 0x20; - request->u.atapi.ccb[9] = request->u.atapi.ccb[5]; - request->u.atapi.ccb[8] = request->u.atapi.ccb[4]; - request->u.atapi.ccb[7] = 0; - request->u.atapi.ccb[6] = 0; - request->u.atapi.ccb[5] = request->u.atapi.ccb[3]; - request->u.atapi.ccb[4] = request->u.atapi.ccb[2]; - request->u.atapi.ccb[3] = request->u.atapi.ccb[1] & 0x1f; - request->u.atapi.ccb[2] = 0; - request->u.atapi.ccb[1] = 0; - /* FALLTHROUGH */ - - case READ_10: - /* FALLTHROUGH */ - case WRITE_10: - /* FALLTHROUGH */ - case READ_12: - /* FALLTHROUGH */ - case WRITE_12: - /* - * Enable DMA (if target supports it) for READ and WRITE commands - * only, as some combinations of drive, controller and chipset do - * not behave correctly when DMA is enabled for other commands. - */ - if (softc->atadev[tid]->mode >= ATA_DMA) - request_flags |= ATA_R_DMA; - break; - - } - - if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN && (len & 1)) { - /* ATA always transfers an even number of bytes */ - if ((buf = hcb->dxfer_alloc - = malloc(++len, M_ATACAM, M_NOWAIT | M_ZERO)) == NULL) { - printf("cannot allocate ATAPI/CAM buffer\n"); - goto action_oom; - } - } - request->dev = softc->atadev[tid]->dev; - request->driver = hcb; - request->data = buf; - request->bytecount = len; - request->transfersize = min(request->bytecount, 65534); - request->timeout = (ccb_h->timeout + 999) / 1000; - request->callback = &atapi_cb; - request->flags = request_flags; - - /* - * no retries are to be performed at the ATA level; any retries - * will be done by CAM. - */ - request->retries = 0; - - TAILQ_INSERT_TAIL(&softc->pending_hcbs, hcb, chain); - hcb->flags |= QUEUED; - ccb_h->status |= CAM_SIM_QUEUED; - mtx_unlock(&softc->state_lock); - - ata_queue_request(request); - mtx_lock(&softc->state_lock); - return; - } - - default: - CAM_DEBUG(ccb_h->path, CAM_DEBUG_SUBTRACE, - ("unsupported function code 0x%02x\n", ccb_h->func_code)); - goto action_invalid; - } - - /* NOTREACHED */ - -action_oom: - if (request != NULL) - ata_free_request(request); - if (hcb != NULL) - free_hcb(hcb); - xpt_print_path(ccb_h->path); - printf("out of memory, freezing queue.\n"); - softc->flags |= RESOURCE_SHORTAGE; - xpt_freeze_simq(sim, /*count*/ 1); - ccb_h->status = CAM_REQUEUE_REQ; - xpt_done(ccb); - return; - -action_invalid: - ccb_h->status = CAM_REQ_INVALID; - xpt_done(ccb); - return; -} - -static void -atapi_poll(struct cam_sim *sim) -{ - struct atapi_xpt_softc *softc = - (struct atapi_xpt_softc*)cam_sim_softc(sim); - - mtx_unlock(&softc->state_lock); - ata_interrupt(softc->ata_ch); - mtx_lock(&softc->state_lock); -} - -static void -atapi_cb(struct ata_request *request) -{ - struct atapi_xpt_softc *scp; - struct atapi_hcb *hcb; - struct ccb_scsiio *csio; - u_int32_t rc; - - hcb = (struct atapi_hcb *)request->driver; - scp = hcb->softc; - csio = &hcb->ccb->csio; - -#ifdef CAMDEBUG -# define err (request->u.atapi.sense.key) - if (CAM_DEBUGGED(csio->ccb_h.path, CAM_DEBUG_CDB)) { - printf("atapi_cb: hcb@%p sense = %02x: sk = %01x%s%s%s\n", - hcb, err, err & 0x0f, - (err & 0x80) ? ", Filemark" : "", - (err & 0x40) ? ", EOM" : "", - (err & 0x20) ? ", ILI" : ""); - device_printf(request->dev, - "cmd %s status %02x result %02x error %02x\n", - ata_cmd2str(request), - request->status, request->result, request->error); - } -#endif - - if ((hcb->flags & AUTOSENSE) != 0) { - rc = CAM_SCSI_STATUS_ERROR; - if (request->result == 0) { - csio->ccb_h.status |= CAM_AUTOSNS_VALID; - } - } else if (request->result != 0) { - if ((request->flags & ATA_R_TIMEOUT) != 0) { - rc = CAM_CMD_TIMEOUT; - } else { - rc = CAM_SCSI_STATUS_ERROR; - csio->scsi_status = SCSI_STATUS_CHECK_COND; - - if ((csio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) { -#if 0 - static const int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0, - sizeof(struct atapi_sense), 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 }; - - bcopy (ccb, request->u.atapi.ccb, sizeof ccb); - request->data = (caddr_t)&csio->sense_data; - request->bytecount = sizeof(struct atapi_sense); - request->transfersize = min(request->bytecount, 65534); - request->timeout = (csio->ccb_h.timeout + 999) / 1000; - request->retries = 2; - request->flags = ATA_R_QUIET|ATA_R_ATAPI|ATA_R_IMMEDIATE; - hcb->flags |= AUTOSENSE; - - ata_queue_request(request); - return; -#else - /* - * Use auto-sense data from the ATA layer, if it has - * issued a REQUEST SENSE automatically and that operation - * returned without error. - */ - if (request->u.atapi.sense.key != 0 && request->error == 0) { - bcopy (&request->u.atapi.sense, &csio->sense_data, sizeof(struct atapi_sense)); - csio->ccb_h.status |= CAM_AUTOSNS_VALID; - } - } -#endif - } - } else { - rc = CAM_REQ_CMP; - csio->scsi_status = SCSI_STATUS_OK; - if (((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) && - hcb->dxfer_alloc != NULL) - { - bcopy(hcb->dxfer_alloc, csio->data_ptr, csio->dxfer_len); - } - } - - mtx_lock(&scp->state_lock); - free_hcb_and_ccb_done(hcb, rc); - mtx_unlock(&scp->state_lock); - - ata_free_request(request); -} - -static void -free_hcb_and_ccb_done(struct atapi_hcb *hcb, u_int32_t status) -{ - struct atapi_xpt_softc *softc; - union ccb *ccb; - - if (hcb == NULL) - return; - - softc = hcb->softc; - ccb = hcb->ccb; - - /* we're about to free a hcb, so the shortage has ended */ - if (softc->flags & RESOURCE_SHORTAGE) { - softc->flags &= ~RESOURCE_SHORTAGE; - status |= CAM_RELEASE_SIMQ; - } - free_hcb(hcb); - ccb->ccb_h.status = - status | (ccb->ccb_h.status & ~(CAM_STATUS_MASK | CAM_SIM_QUEUED)); - xpt_done(ccb); -} - -static void -atapi_async(void *callback_arg, u_int32_t code, - struct cam_path* path, void *arg) -{ - int targ; - - GIANT_REQUIRED; - - switch (code) { - case AC_LOST_DEVICE: - targ = xpt_path_target_id(path); - xpt_print_path(path); - if (targ == -1) - printf("Lost host adapter\n"); - else - printf("Lost target %d???\n", targ); - break; - - default: - break; - } -} - -static void -cam_rescan(struct cam_sim *sim) -{ - union ccb *ccb; - - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) - return; - if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, cam_sim_path(sim), - CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_free_ccb(ccb); - return; - } - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("Rescanning ATAPI bus.\n")); - xpt_rescan(ccb); - /* scan is in progress now */ -} - -static struct atapi_hcb * -allocate_hcb(struct atapi_xpt_softc *softc, int unit, int bus, union ccb *ccb) -{ - struct atapi_hcb *hcb = (struct atapi_hcb *) - malloc(sizeof(struct atapi_hcb), M_ATACAM, M_NOWAIT | M_ZERO); - - if (hcb != NULL) { - hcb->softc = softc; - hcb->unit = unit; - hcb->bus = bus; - hcb->ccb = ccb; - } - return hcb; -} - -static void -free_hcb(struct atapi_hcb *hcb) -{ - if ((hcb->flags & QUEUED) != 0) - TAILQ_REMOVE(&hcb->softc->pending_hcbs, hcb, chain); - if (hcb->dxfer_alloc != NULL) - free(hcb->dxfer_alloc, M_ATACAM); - free(hcb, M_ATACAM); -} - -static void -free_softc(struct atapi_xpt_softc *scp) -{ - struct atapi_hcb *hcb, *thcb; - - if (scp != NULL) { - mtx_lock(&scp->state_lock); - TAILQ_FOREACH_SAFE(hcb, &scp->pending_hcbs, chain, thcb) { - free_hcb_and_ccb_done(hcb, CAM_UNREC_HBA_ERROR); - } - if (scp->path != NULL) { - setup_async_cb(scp, 0); - xpt_free_path(scp->path); - } - if ((scp->flags & BUS_REGISTERED) != 0) { - if (xpt_bus_deregister(cam_sim_path(scp->sim)) == CAM_REQ_CMP) - scp->flags &= ~BUS_REGISTERED; - } - if (scp->sim != NULL) { - if ((scp->flags & BUS_REGISTERED) == 0) - cam_sim_free(scp->sim, /*free_devq*/TRUE); - else - printf("Can't free %s SIM (still registered)\n", - cam_sim_name(scp->sim)); - } - mtx_destroy(&scp->state_lock); - } -} - -static int -atapi_cam_event_handler(module_t mod, int what, void *arg) { - device_t *devlist; - int devcount; - - switch (what) { - case MOD_UNLOAD: - if (devclass_get_devices(atapi_cam_devclass, &devlist, &devcount) - != 0) - return ENXIO; - if (devlist != NULL) { - while (devlist != NULL && devcount > 0) { - device_t child = devlist[--devcount]; - struct atapi_xpt_softc *scp = device_get_softc(child); - - device_delete_child(device_get_parent(child),child); - if (scp != NULL) - free(scp, M_ATACAM); - } - free(devlist, M_TEMP); - } - break; - - default: - break; - } - return 0; -} diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c deleted file mode 100644 index a45c384..0000000 --- a/sys/dev/ata/atapi-cd.c +++ /dev/null @@ -1,1921 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ata.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* prototypes */ -static void acd_geom_attach(void *, int); -static void acd_geom_detach(void *, int); -static void acd_set_ioparm(device_t); -static void acd_describe(device_t); -static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *); -static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t); -static int acd_geom_access(struct g_provider *, int, int, int); -static g_ioctl_t acd_geom_ioctl; -static void acd_geom_start(struct bio *); -static void acd_strategy(struct bio *); -static void acd_done(struct ata_request *); -static void acd_read_toc(device_t); -static int acd_play(device_t, int, int); -static int acd_setchan(device_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t); -static int acd_init_writer(device_t, int); -static int acd_fixate(device_t, int); -static int acd_init_track(device_t, struct cdr_track *); -static int acd_flush(device_t); -static int acd_read_track_info(device_t, int32_t, struct acd_track_info *); -static int acd_get_progress(device_t, int *); -static int acd_send_cue(device_t, struct cdr_cuesheet *); -static int acd_report_key(device_t, struct dvd_authinfo *); -static int acd_send_key(device_t, struct dvd_authinfo *); -static int acd_read_structure(device_t, struct dvd_struct *); -static int acd_tray(device_t, int); -static int acd_blank(device_t, int); -static int acd_prevent_allow(device_t, int); -static int acd_start_stop(device_t, int); -static int acd_pause_resume(device_t, int); -static int acd_mode_sense(device_t, int, caddr_t, int); -static int acd_mode_select(device_t, caddr_t, int); -static int acd_set_speed(device_t, int, int); -static void acd_get_cap(device_t); -static int acd_read_format_caps(device_t, struct cdr_format_capacities *); -static int acd_format(device_t, struct cdr_format_params *); -static int acd_test_ready(device_t); - -/* internal vars */ -static MALLOC_DEFINE(M_ACD, "acd_driver", "ATAPI CD driver buffers"); -static struct g_class acd_class = { - .name = "ACD", - .version = G_VERSION, - .access = acd_geom_access, - .ioctl = acd_geom_ioctl, - .start = acd_geom_start, -}; -//DECLARE_GEOM_CLASS(acd_class, acd); - -static int -acd_probe(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if ((atadev->param.config & ATA_PROTO_ATAPI) && - (atadev->param.config & ATA_ATAPI_TYPE_MASK) == ATA_ATAPI_TYPE_CDROM) - return 0; - else - return ENXIO; -} - -static int -acd_attach(device_t dev) -{ - struct acd_softc *cdp; - - if (!(cdp = malloc(sizeof(struct acd_softc), M_ACD, M_NOWAIT | M_ZERO))) { - device_printf(dev, "out of memory\n"); - return ENOMEM; - } - cdp->block_size = 2048; - device_set_ivars(dev, cdp); - ata_setmode(dev); - ata_controlcmd(dev, ATA_DEVICE_RESET, 0, 0, 0); - acd_get_cap(dev); - g_post_event(acd_geom_attach, dev, M_WAITOK, NULL); - - /* announce we are here */ - acd_describe(dev); - return 0; -} - -static int -acd_detach(device_t dev) -{ - g_waitfor_event(acd_geom_detach, dev, M_WAITOK, NULL); - return 0; -} - -static int -acd_shutdown(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); - return 0; -} - -static int -acd_reinit(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - - /* if detach pending, return error */ - if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) - return 1; - - ata_setmode(dev); - return 0; -} - -static void -acd_geom_attach(void *arg, int flag) -{ - struct ata_device *atadev = device_get_softc(arg); - struct acd_softc *cdp = device_get_ivars(arg); - struct g_geom *gp; - struct g_provider *pp; - - g_topology_assert(); - gp = g_new_geomf(&acd_class, "acd%d", device_get_unit(arg)); - gp->softc = arg; - cdp->gp = gp; - pp = g_new_providerf(gp, "acd%d", device_get_unit(arg)); - pp->index = 0; - cdp->pp[0] = pp; - g_error_provider(pp, 0); - atadev->flags |= ATA_D_MEDIA_CHANGED; - acd_set_ioparm(arg); -} - -static void -acd_geom_detach(void *arg, int flag) -{ - struct acd_softc *cdp = device_get_ivars(arg); - - /* signal geom so we dont get any further requests */ - g_wither_geom(cdp->gp, ENXIO); - - /* fail requests on the queue and any thats "in flight" for this device */ - ata_fail_requests(arg); - - /* dont leave anything behind */ - device_set_ivars(arg, NULL); - free(cdp, M_ACD); -} - -static int -acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, int fflag, struct thread *td) -{ - device_t dev = pp->geom->softc; - struct ata_device *atadev = device_get_softc(dev); - struct acd_softc *cdp = device_get_ivars(dev); - int error = 0, nocopyout = 0; - - if (!cdp) - return ENXIO; - - if (atadev->flags & ATA_D_MEDIA_CHANGED) { - switch (cmd) { - case CDIOCRESET: - acd_test_ready(dev); - break; - - default: - acd_read_toc(dev); - acd_prevent_allow(dev, 1); - cdp->flags |= F_LOCKED; - break; - } - } - - switch (cmd) { - - case CDIOCRESUME: - error = acd_pause_resume(dev, 1); - break; - - case CDIOCPAUSE: - error = acd_pause_resume(dev, 0); - break; - - case CDIOCSTART: - error = acd_start_stop(dev, 1); - break; - - case CDIOCSTOP: - error = acd_start_stop(dev, 0); - break; - - case CDIOCALLOW: - error = acd_prevent_allow(dev, 0); - cdp->flags &= ~F_LOCKED; - break; - - case CDIOCPREVENT: - error = acd_prevent_allow(dev, 1); - cdp->flags |= F_LOCKED; - break; - - /* - * XXXRW: Why does this require privilege? - */ - case CDIOCRESET: - error = priv_check(td, PRIV_DRIVER); - if (error) - break; - error = acd_test_ready(dev); - break; - - case CDIOCEJECT: - if (pp->acr != 1) { - error = EBUSY; - break; - } - error = acd_tray(dev, 0); - break; - - case CDIOCCLOSE: - if (pp->acr != 1) - break; - error = acd_tray(dev, 1); - break; - - case CDIOREADTOCHEADER: - if (!cdp->toc.hdr.ending_track) { - error = EIO; - break; - } - bcopy(&cdp->toc.hdr, addr, sizeof(cdp->toc.hdr)); - break; - - case CDIOREADTOCENTRYS: - { - struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr; - struct toc *toc = &cdp->toc; - int starting_track = te->starting_track; - int len; - - if (!toc->hdr.ending_track) { - error = EIO; - break; - } - - if (te->data_len < sizeof(toc->tab[0]) || - (te->data_len % sizeof(toc->tab[0])) != 0 || - (te->address_format != CD_MSF_FORMAT && - te->address_format != CD_LBA_FORMAT)) { - error = EINVAL; - break; - } - - if (!starting_track) - starting_track = toc->hdr.starting_track; - else if (starting_track == 170) - starting_track = toc->hdr.ending_track + 1; - else if (starting_track < toc->hdr.starting_track || - starting_track > toc->hdr.ending_track + 1) { - error = EINVAL; - break; - } - - len = ((toc->hdr.ending_track + 1 - starting_track) + 1) * - sizeof(toc->tab[0]); - if (te->data_len < len) - len = te->data_len; - if (len > sizeof(toc->tab)) { - error = EINVAL; - break; - } - - if (te->address_format == CD_MSF_FORMAT) { - struct cd_toc_entry *entry; - - if (!(toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT))) { - error = ENOMEM; - break; - } - bcopy(&cdp->toc, toc, sizeof(struct toc)); - entry = toc->tab + (toc->hdr.ending_track + 1 - - toc->hdr.starting_track) + 1; - while (--entry >= toc->tab) { - lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute, - &entry->addr.msf.second, &entry->addr.msf.frame); - entry->addr_type = CD_MSF_FORMAT; - } - } - error = copyout(toc->tab + starting_track - toc->hdr.starting_track, - te->data, len); - if (te->address_format == CD_MSF_FORMAT) - free(toc, M_ACD); - } - break; - - case CDIOREADTOCENTRY: - { - struct ioc_read_toc_single_entry *te = - (struct ioc_read_toc_single_entry *)addr; - struct toc *toc = &cdp->toc; - u_char track = te->track; - - if (!toc->hdr.ending_track) { - error = EIO; - break; - } - - if (te->address_format != CD_MSF_FORMAT && - te->address_format != CD_LBA_FORMAT) { - error = EINVAL; - break; - } - - if (!track) - track = toc->hdr.starting_track; - else if (track == 170) - track = toc->hdr.ending_track + 1; - else if (track < toc->hdr.starting_track || - track > toc->hdr.ending_track + 1) { - error = EINVAL; - break; - } - - if (te->address_format == CD_MSF_FORMAT) { - struct cd_toc_entry *entry; - - if (!(toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT))) { - error = ENOMEM; - break; - } - bcopy(&cdp->toc, toc, sizeof(struct toc)); - entry = toc->tab + (track - toc->hdr.starting_track); - lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute, - &entry->addr.msf.second, &entry->addr.msf.frame); - } - bcopy(toc->tab + track - toc->hdr.starting_track, - &te->entry, sizeof(struct cd_toc_entry)); - if (te->address_format == CD_MSF_FORMAT) - free(toc, M_ACD); - } - break; - -#if __FreeBSD_version > 600008 - case CDIOCREADSUBCHANNEL_SYSSPACE: - nocopyout = 1; - /* FALLTHROUGH */ - -#endif - case CDIOCREADSUBCHANNEL: - { - struct ioc_read_subchannel *args = - (struct ioc_read_subchannel *)addr; - u_int8_t format; - int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0, - sizeof(cdp->subchan)>>8, sizeof(cdp->subchan), - 0, 0, 0, 0, 0, 0, 0 }; - - if (args->data_len > sizeof(struct cd_sub_channel_info) || - args->data_len < sizeof(struct cd_sub_channel_header)) { - error = EINVAL; - break; - } - - format = args->data_format; - if ((format != CD_CURRENT_POSITION) && - (format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) { - error = EINVAL; - break; - } - - ccb[1] = args->address_format & CD_MSF_FORMAT; - - if ((error = ata_atapicmd(dev, ccb, (caddr_t)&cdp->subchan, - sizeof(cdp->subchan), ATA_R_READ, 10))) - break; - - if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) { - if (cdp->subchan.header.audio_status == 0x11) { - error = EINVAL; - break; - } - - ccb[3] = format; - if (format == CD_TRACK_INFO) - ccb[6] = args->track; - - if ((error = ata_atapicmd(dev, ccb, (caddr_t)&cdp->subchan, - sizeof(cdp->subchan),ATA_R_READ,10))){ - break; - } - } - if (nocopyout == 0) { - error = copyout(&cdp->subchan, args->data, args->data_len); - } else { - error = 0; - bcopy(&cdp->subchan, args->data, args->data_len); - } - } - break; - - case CDIOCPLAYMSF: - { - struct ioc_play_msf *args = (struct ioc_play_msf *)addr; - - error = - acd_play(dev, - msf2lba(args->start_m, args->start_s, args->start_f), - msf2lba(args->end_m, args->end_s, args->end_f)); - } - break; - - case CDIOCPLAYBLOCKS: - { - struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr; - - error = acd_play(dev, args->blk, args->blk + args->len); - } - break; - - case CDIOCPLAYTRACKS: - { - struct ioc_play_track *args = (struct ioc_play_track *)addr; - int t1, t2; - - if (!cdp->toc.hdr.ending_track) { - error = EIO; - break; - } - if (args->end_track < cdp->toc.hdr.ending_track + 1) - ++args->end_track; - if (args->end_track > cdp->toc.hdr.ending_track + 1) - args->end_track = cdp->toc.hdr.ending_track + 1; - t1 = args->start_track - cdp->toc.hdr.starting_track; - t2 = args->end_track - cdp->toc.hdr.starting_track; - if (t1 < 0 || t2 < 0 || - t1 > (cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track)) { - error = EINVAL; - break; - } - error = acd_play(dev, ntohl(cdp->toc.tab[t1].addr.lba), - ntohl(cdp->toc.tab[t2].addr.lba)); - } - break; - - case CDIOCGETVOL: - { - struct ioc_vol *arg = (struct ioc_vol *)addr; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_AUDIO_PAGE, - (caddr_t)&cdp->au, sizeof(cdp->au)))) - break; - - if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) { - error = EIO; - break; - } - arg->vol[0] = cdp->au.port[0].volume; - arg->vol[1] = cdp->au.port[1].volume; - arg->vol[2] = cdp->au.port[2].volume; - arg->vol[3] = cdp->au.port[3].volume; - } - break; - - case CDIOCSETVOL: - { - struct ioc_vol *arg = (struct ioc_vol *)addr; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_AUDIO_PAGE, - (caddr_t)&cdp->au, sizeof(cdp->au)))) - break; - if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) { - error = EIO; - break; - } - if ((error = acd_mode_sense(dev, ATAPI_CDROM_AUDIO_PAGE_MASK, - (caddr_t)&cdp->aumask, - sizeof(cdp->aumask)))) - break; - cdp->au.data_length = 0; - cdp->au.port[0].channels = CHANNEL_0; - cdp->au.port[1].channels = CHANNEL_1; - cdp->au.port[0].volume = arg->vol[0] & cdp->aumask.port[0].volume; - cdp->au.port[1].volume = arg->vol[1] & cdp->aumask.port[1].volume; - cdp->au.port[2].volume = arg->vol[2] & cdp->aumask.port[2].volume; - cdp->au.port[3].volume = arg->vol[3] & cdp->aumask.port[3].volume; - error = acd_mode_select(dev, (caddr_t)&cdp->au, sizeof(cdp->au)); - } - break; - - case CDIOCSETPATCH: - { - struct ioc_patch *arg = (struct ioc_patch *)addr; - - error = acd_setchan(dev, arg->patch[0], arg->patch[1], - arg->patch[2], arg->patch[3]); - } - break; - - case CDIOCSETMONO: - error = acd_setchan(dev, CHANNEL_0|CHANNEL_1, CHANNEL_0|CHANNEL_1, 0,0); - break; - - case CDIOCSETSTEREO: - error = acd_setchan(dev, CHANNEL_0, CHANNEL_1, 0, 0); - break; - - case CDIOCSETMUTE: - error = acd_setchan(dev, 0, 0, 0, 0); - break; - - case CDIOCSETLEFT: - error = acd_setchan(dev, CHANNEL_0, CHANNEL_0, 0, 0); - break; - - case CDIOCSETRIGHT: - error = acd_setchan(dev, CHANNEL_1, CHANNEL_1, 0, 0); - break; - - case CDRIOCBLANK: - error = acd_blank(dev, (*(int *)addr)); - break; - - case CDRIOCNEXTWRITEABLEADDR: - { - struct acd_track_info track_info; - - if ((error = acd_read_track_info(dev, 0xff, &track_info))) - break; - - if (!track_info.nwa_valid) { - error = EINVAL; - break; - } - *(int*)addr = track_info.next_writeable_addr; - } - break; - - case CDRIOCINITWRITER: - error = acd_init_writer(dev, (*(int *)addr)); - break; - - case CDRIOCINITTRACK: - error = acd_init_track(dev, (struct cdr_track *)addr); - break; - - case CDRIOCFLUSH: - error = acd_flush(dev); - break; - - case CDRIOCFIXATE: - error = acd_fixate(dev, (*(int *)addr)); - break; - - case CDRIOCREADSPEED: - { - int speed = *(int *)addr; - - /* Preserve old behavior: units in multiples of CDROM speed */ - if (speed < 177) - speed *= 177; - error = acd_set_speed(dev, speed, CDR_MAX_SPEED); - } - break; - - case CDRIOCWRITESPEED: - { - int speed = *(int *)addr; - - if (speed < 177) - speed *= 177; - error = acd_set_speed(dev, CDR_MAX_SPEED, speed); - } - break; - - case CDRIOCGETBLOCKSIZE: - *(int *)addr = cdp->block_size; - break; - - case CDRIOCSETBLOCKSIZE: - cdp->block_size = *(int *)addr; - pp->sectorsize = cdp->block_size; /* hack for GEOM SOS */ - acd_set_ioparm(dev); - break; - - case CDRIOCGETPROGRESS: - error = acd_get_progress(dev, (int *)addr); - break; - - case CDRIOCSENDCUE: - error = acd_send_cue(dev, (struct cdr_cuesheet *)addr); - break; - - case CDRIOCREADFORMATCAPS: - error = acd_read_format_caps(dev, (struct cdr_format_capacities *)addr); - break; - - case CDRIOCFORMAT: - error = acd_format(dev, (struct cdr_format_params *)addr); - break; - - case DVDIOCREPORTKEY: - if (cdp->cap.media & MST_READ_DVDROM) - error = acd_report_key(dev, (struct dvd_authinfo *)addr); - else - error = EINVAL; - break; - - case DVDIOCSENDKEY: - if (cdp->cap.media & MST_READ_DVDROM) - error = acd_send_key(dev, (struct dvd_authinfo *)addr); - else - error = EINVAL; - break; - - case DVDIOCREADSTRUCTURE: - if (cdp->cap.media & MST_READ_DVDROM) - error = acd_read_structure(dev, (struct dvd_struct *)addr); - else - error = EINVAL; - break; - - default: - error = ata_device_ioctl(dev, cmd, addr); - } - return error; -} - -static int -acd_geom_access(struct g_provider *pp, int dr, int dw, int de) -{ - device_t dev = pp->geom->softc; - struct acd_softc *cdp = device_get_ivars(dev); - struct ata_request *request; - int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int timeout = 60, track; - - if (!(request = ata_alloc_request())) - return ENOMEM; - - /* wait if drive is not finished loading the medium */ - while (timeout--) { - request->dev = dev; - bcopy(ccb, request->u.atapi.ccb, 16); - request->flags = ATA_R_ATAPI; - request->timeout = ATA_REQUEST_TIMEOUT; - ata_queue_request(request); - if (!request->error && - (request->u.atapi.sense.key == 2 || - request->u.atapi.sense.key == 7) && - request->u.atapi.sense.asc == 4 && - request->u.atapi.sense.ascq == 1) - pause("acdld", hz / 2); - else - break; - } - ata_free_request(request); - - if (pp->acr == 0) { - acd_prevent_allow(dev, 1); - cdp->flags |= F_LOCKED; - acd_read_toc(dev); - } - - if (dr + pp->acr == 0) { - acd_prevent_allow(dev, 0); - cdp->flags &= ~F_LOCKED; - } - - if ((track = pp->index)) { - pp->sectorsize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352; - pp->mediasize = ntohl(cdp->toc.tab[track].addr.lba) - - ntohl(cdp->toc.tab[track - 1].addr.lba); - } - else { - pp->sectorsize = cdp->block_size; - pp->mediasize = cdp->disk_size; - } - pp->mediasize *= pp->sectorsize; - - return 0; -} - -static void -acd_geom_start(struct bio *bp) -{ - device_t dev = bp->bio_to->geom->softc; - struct acd_softc *cdp = device_get_ivars(dev); - - if (bp->bio_cmd != BIO_READ && bp->bio_cmd != BIO_WRITE) { - g_io_deliver(bp, EOPNOTSUPP); - return; - } - - if (bp->bio_cmd == BIO_READ && cdp->disk_size == -1) { - g_io_deliver(bp, EIO); - return; - } - - /* GEOM classes must do their own request limiting */ - if (bp->bio_length <= cdp->iomax) { - bp->bio_pblkno = bp->bio_offset / bp->bio_to->sectorsize; - acd_strategy(bp); - } - else { - u_int pos, size = cdp->iomax - cdp->iomax % bp->bio_to->sectorsize; - struct bio *bp2, *bp3; - - if (!(bp2 = g_clone_bio(bp))) - g_io_deliver(bp, EIO); - - for (pos = 0; bp2; pos += size) { - bp3 = NULL; - bp2->bio_done = g_std_done; - bp2->bio_to = bp->bio_to; - bp2->bio_offset += pos; - bp2->bio_data += pos; - bp2->bio_length = bp->bio_length - pos; - if (bp2->bio_length > size) { - bp2->bio_length = size; - if (!(bp3 = g_clone_bio(bp))) - bp->bio_error = ENOMEM; - } - bp2->bio_pblkno = bp2->bio_offset / bp2->bio_to->sectorsize; - acd_strategy(bp2); - bp2 = bp3; - } - } -} - -static void -acd_strategy(struct bio *bp) -{ - device_t dev = bp->bio_to->geom->softc; - struct ata_device *atadev = device_get_softc(dev); - struct acd_softc *cdp = device_get_ivars(dev); - struct ata_request *request; - u_int32_t lba, lastlba, count; - int8_t ccb[16]; - int track, blocksize; - - /* reject all queued entries if media changed */ - if (atadev->flags & ATA_D_MEDIA_CHANGED) { - g_io_deliver(bp, EIO); - return; - } - - bzero(ccb, sizeof(ccb)); - - track = bp->bio_to->index; - - if (track) { - blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352; - lastlba = ntohl(cdp->toc.tab[track].addr.lba); - lba = bp->bio_offset / blocksize; - lba += ntohl(cdp->toc.tab[track - 1].addr.lba); - } - else { - blocksize = cdp->block_size; - lastlba = cdp->disk_size; - lba = bp->bio_offset / blocksize; - } - - count = bp->bio_length / blocksize; - - if (bp->bio_cmd == BIO_READ) { - /* if transfer goes beyond range adjust it to be within limits */ - if (lba + count > lastlba) { - /* if we are entirely beyond EOM return EOF */ - if (lastlba <= lba) { - g_io_deliver(bp, 0); - return; - } - count = lastlba - lba; - } - switch (blocksize) { - case 2048: - ccb[0] = ATAPI_READ_BIG; - break; - - case 2352: - ccb[0] = ATAPI_READ_CD; - ccb[9] = 0xf8; - break; - - default: - ccb[0] = ATAPI_READ_CD; - ccb[9] = 0x10; - } - } - else - ccb[0] = ATAPI_WRITE_BIG; - - ccb[1] = 0; - ccb[2] = lba>>24; - ccb[3] = lba>>16; - ccb[4] = lba>>8; - ccb[5] = lba; - ccb[6] = count>>16; - ccb[7] = count>>8; - ccb[8] = count; - - if (!(request = ata_alloc_request())) { - g_io_deliver(bp, ENOMEM); - return; - } - request->dev = dev; - request->bio = bp; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = bp->bio_data; - request->bytecount = count * blocksize; - request->transfersize = min(request->bytecount, 65534); - request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30; - request->retries = 2; - request->callback = acd_done; - request->flags = ATA_R_ATAPI; - if (atadev->mode >= ATA_DMA) - request->flags |= ATA_R_DMA; - switch (bp->bio_cmd) { - case BIO_READ: - request->flags |= ATA_R_READ; - break; - case BIO_WRITE: - request->flags |= ATA_R_WRITE; - break; - default: - device_printf(dev, "unknown BIO operation\n"); - ata_free_request(request); - g_io_deliver(bp, EIO); - return; - } - ata_queue_request(request); -} - -static void -acd_done(struct ata_request *request) -{ - struct bio *bp = request->bio; - - /* finish up transfer */ - bp->bio_completed = request->donecount; - g_io_deliver(bp, request->result); - ata_free_request(request); -} - -static void -acd_set_ioparm(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct acd_softc *cdp = device_get_ivars(dev); - uint32_t max_iosize; - - max_iosize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; - - cdp->iomax = min(max_iosize, 65534); -} - -static void -lba2msf(u_int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f) -{ - lba += 150; - lba &= 0xffffff; - *m = lba / (60 * 75); - lba %= (60 * 75); - *s = lba / 75; - *f = lba % 75; -} - -static u_int32_t -msf2lba(u_int8_t m, u_int8_t s, u_int8_t f) -{ - return (m * 60 + s) * 75 + f - 150; -} - -static void -acd_read_toc(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - struct acd_softc *cdp = device_get_ivars(dev); - struct g_provider *pp; - u_int32_t sizes[2]; - int8_t ccb[16]; - int track, ntracks, len; - - atadev->flags &= ~ATA_D_MEDIA_CHANGED; - bzero(&cdp->toc, sizeof(cdp->toc)); - cdp->disk_size = -1; /* hack for GEOM SOS */ - - if (acd_test_ready(dev)) - return; - - bzero(ccb, sizeof(ccb)); - len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry); - ccb[0] = ATAPI_READ_TOC; - ccb[7] = len>>8; - ccb[8] = len; - if (ata_atapicmd(dev, ccb, (caddr_t)&cdp->toc, len, - ATA_R_READ | ATA_R_QUIET, 30)) { - bzero(&cdp->toc, sizeof(cdp->toc)); - return; - } - ntracks = cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1; - if (ntracks <= 0 || ntracks > MAXTRK) { - bzero(&cdp->toc, sizeof(cdp->toc)); - return; - } - - len = sizeof(struct ioc_toc_header)+(ntracks+1)*sizeof(struct cd_toc_entry); - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_READ_TOC; - ccb[7] = len>>8; - ccb[8] = len; - if (ata_atapicmd(dev, ccb, (caddr_t)&cdp->toc, len, - ATA_R_READ | ATA_R_QUIET, 30)) { - bzero(&cdp->toc, sizeof(cdp->toc)); - return; - } - cdp->toc.hdr.len = ntohs(cdp->toc.hdr.len); - - cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352; - acd_set_ioparm(dev); - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_READ_CAPACITY; - if (ata_atapicmd(dev, ccb, (caddr_t)sizes, sizeof(sizes), - ATA_R_READ | ATA_R_QUIET, 30)) { - bzero(&cdp->toc, sizeof(cdp->toc)); - return; - } - cdp->disk_size = ntohl(sizes[0]) + 1; - - for (track = 1; track <= ntracks; track ++) { - if (cdp->pp[track] != NULL) - continue; - pp = g_new_providerf(cdp->gp, "acd%dt%02d", device_get_unit(dev),track); - pp->index = track; - cdp->pp[track] = pp; - g_error_provider(pp, 0); - } - for (; track < MAXTRK; track ++) { - if (cdp->pp[track] == NULL) - continue; - cdp->pp[track]->flags |= G_PF_WITHER; - g_orphan_provider(cdp->pp[track], ENXIO); - cdp->pp[track] = NULL; - } - -#ifdef ACD_DEBUG - if (cdp->disk_size && cdp->toc.hdr.ending_track) { - device_printf(dev, "(%d sectors (%d bytes)), %d tracks ", - cdp->disk_size, cdp->block_size, - cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track+1); - if (cdp->toc.tab[0].control & 4) - printf("%dMB\n", cdp->disk_size * cdp->block_size / 1048576); - else - printf("%d:%d audio\n", - cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60); - } -#endif -} - -static int -acd_play(device_t dev, int start, int end) -{ - int8_t ccb[16]; - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_PLAY_MSF; - lba2msf(start, &ccb[3], &ccb[4], &ccb[5]); - lba2msf(end, &ccb[6], &ccb[7], &ccb[8]); - return ata_atapicmd(dev, ccb, NULL, 0, 0, 10); -} - -static int -acd_setchan(device_t dev, u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3) -{ - struct acd_softc *cdp = device_get_ivars(dev); - int error; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_AUDIO_PAGE, (caddr_t)&cdp->au, - sizeof(cdp->au)))) - return error; - if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) - return EIO; - cdp->au.data_length = 0; - cdp->au.port[0].channels = c0; - cdp->au.port[1].channels = c1; - cdp->au.port[2].channels = c2; - cdp->au.port[3].channels = c3; - return acd_mode_select(dev, (caddr_t)&cdp->au, sizeof(cdp->au)); -} - -static int -acd_init_writer(device_t dev, int test_write) -{ - int8_t ccb[16]; - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_REZERO; - ata_atapicmd(dev, ccb, NULL, 0, ATA_R_QUIET, 60); - ccb[0] = ATAPI_SEND_OPC_INFO; - ccb[1] = 0x01; - ata_atapicmd(dev, ccb, NULL, 0, ATA_R_QUIET, 30); - return 0; -} - -static int -acd_fixate(device_t dev, int multisession) -{ - struct acd_softc *cdp = device_get_ivars(dev); - int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0x01, 0x02, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int timeout = 5*60*2; - int error, dummy; - struct write_param param; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_WRITE_PARAMETERS_PAGE, - (caddr_t)¶m, sizeof(param)))) - return error; - - param.data_length = 0; - if (multisession) - param.session_type = CDR_SESS_MULTI; - else - param.session_type = CDR_SESS_NONE; - - if ((error = acd_mode_select(dev, (caddr_t)¶m, param.page_length + 10))) - return error; - - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 30); - if (error) - return error; - - /* some drives just return ready, wait for the expected fixate time */ - if ((error = acd_test_ready(dev)) != EBUSY) { - timeout = timeout / (cdp->cap.cur_write_speed / 177); - pause("acdfix", timeout * hz / 2); - return acd_test_ready(dev); - } - - while (timeout-- > 0) { - if ((error = acd_get_progress(dev, &dummy))) - return error; - if ((error = acd_test_ready(dev)) != EBUSY) - return error; - pause("acdcld", hz / 2); - } - return EIO; -} - -static int -acd_init_track(device_t dev, struct cdr_track *track) -{ - struct acd_softc *cdp = device_get_ivars(dev); - struct write_param param; - int error; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_WRITE_PARAMETERS_PAGE, - (caddr_t)¶m, sizeof(param)))) - return error; - - param.data_length = 0; - param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE; - param.page_length = 0x32; - param.test_write = track->test_write ? 1 : 0; - param.write_type = CDR_WTYPE_TRACK; - param.session_type = CDR_SESS_NONE; - param.fp = 0; - param.packet_size = 0; - - if (cdp->cap.capabilities & MST_BURNPROOF) - param.burnproof = 1; - - switch (track->datablock_type) { - - case CDR_DB_RAW: - if (track->preemp) - param.track_mode = CDR_TMODE_AUDIO_PREEMP; - else - param.track_mode = CDR_TMODE_AUDIO; - cdp->block_size = 2352; - param.datablock_type = CDR_DB_RAW; - param.session_format = CDR_SESS_CDROM; - break; - - case CDR_DB_ROM_MODE1: - cdp->block_size = 2048; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_ROM_MODE1; - param.session_format = CDR_SESS_CDROM; - break; - - case CDR_DB_ROM_MODE2: - cdp->block_size = 2336; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_ROM_MODE2; - param.session_format = CDR_SESS_CDROM; - break; - - case CDR_DB_XA_MODE1: - cdp->block_size = 2048; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_XA_MODE1; - param.session_format = CDR_SESS_CDROM_XA; - break; - - case CDR_DB_XA_MODE2_F1: - cdp->block_size = 2056; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_XA_MODE2_F1; - param.session_format = CDR_SESS_CDROM_XA; - break; - - case CDR_DB_XA_MODE2_F2: - cdp->block_size = 2324; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_XA_MODE2_F2; - param.session_format = CDR_SESS_CDROM_XA; - break; - - case CDR_DB_XA_MODE2_MIX: - cdp->block_size = 2332; - param.track_mode = CDR_TMODE_DATA; - param.datablock_type = CDR_DB_XA_MODE2_MIX; - param.session_format = CDR_SESS_CDROM_XA; - break; - } - acd_set_ioparm(dev); - return acd_mode_select(dev, (caddr_t)¶m, param.page_length + 10); -} - -static int -acd_flush(device_t dev) -{ - int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, ATA_R_QUIET, 60); -} - -static int -acd_read_track_info(device_t dev, int32_t lba, struct acd_track_info *info) -{ - int8_t ccb[16] = { ATAPI_READ_TRACK_INFO, 1, - lba>>24, lba>>16, lba>>8, lba, 0, - sizeof(*info)>>8, sizeof(*info), - 0, 0, 0, 0, 0, 0, 0 }; - int error; - - if ((error = ata_atapicmd(dev, ccb, (caddr_t)info, sizeof(*info), - ATA_R_READ, 30))) - return error; - info->data_length = ntohs(info->data_length); - info->track_start_addr = ntohl(info->track_start_addr); - info->next_writeable_addr = ntohl(info->next_writeable_addr); - info->free_blocks = ntohl(info->free_blocks); - info->fixed_packet_size = ntohl(info->fixed_packet_size); - info->track_length = ntohl(info->track_length); - return 0; -} - -static int -acd_get_progress(device_t dev, int *finished) -{ - int8_t ccb[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - struct ata_request *request; - int8_t dummy[8]; - - if (!(request = ata_alloc_request())) - return ENOMEM; - - request->dev = dev; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = dummy; - request->bytecount = sizeof(dummy); - request->transfersize = min(request->bytecount, 65534); - request->flags = ATA_R_ATAPI | ATA_R_READ; - request->timeout = 30; - ata_queue_request(request); - if (!request->error && - request->u.atapi.sense.specific & ATA_SENSE_SPEC_VALID) - *finished = ((request->u.atapi.sense.specific2 | - (request->u.atapi.sense.specific1 << 8)) * 100) / 65535; - else - *finished = 0; - ata_free_request(request); - return 0; -} - -static int -acd_send_cue(device_t dev, struct cdr_cuesheet *cuesheet) -{ - struct acd_softc *cdp = device_get_ivars(dev); - struct write_param param; - int8_t ccb[16] = { ATAPI_SEND_CUE_SHEET, 0, 0, 0, 0, 0, - cuesheet->len>>16, cuesheet->len>>8, cuesheet->len, - 0, 0, 0, 0, 0, 0, 0 }; - int8_t *buffer; - int32_t error; - - if ((error = acd_mode_sense(dev, ATAPI_CDROM_WRITE_PARAMETERS_PAGE, - (caddr_t)¶m, sizeof(param)))) - return error; - - param.data_length = 0; - param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE; - param.page_length = 0x32; - param.test_write = cuesheet->test_write ? 1 : 0; - param.write_type = CDR_WTYPE_SESSION; - param.session_type = cuesheet->session_type; - param.fp = 0; - param.packet_size = 0; - param.track_mode = CDR_TMODE_AUDIO; - param.datablock_type = CDR_DB_RAW; - param.session_format = cuesheet->session_format; - if (cdp->cap.capabilities & MST_BURNPROOF) - param.burnproof = 1; - - if ((error = acd_mode_select(dev, (caddr_t)¶m, param.page_length + 10))) - return error; - - if (!(buffer = malloc(cuesheet->len, M_ACD, M_NOWAIT))) - return ENOMEM; - - if (!(error = copyin(cuesheet->entries, buffer, cuesheet->len))) - error = ata_atapicmd(dev, ccb, buffer, cuesheet->len, 0, 30); - free(buffer, M_ACD); - return error; -} - -static int -acd_report_key(device_t dev, struct dvd_authinfo *ai) -{ - struct dvd_miscauth *d = NULL; - u_int32_t lba = 0; - int16_t length; - int8_t ccb[16]; - int error; - - switch (ai->format) { - case DVD_REPORT_AGID: - case DVD_REPORT_ASF: - case DVD_REPORT_RPC: - length = 8; - break; - case DVD_REPORT_KEY1: - length = 12; - break; - case DVD_REPORT_TITLE_KEY: - length = 12; - lba = ai->lba; - break; - case DVD_REPORT_CHALLENGE: - length = 16; - break; - case DVD_INVALIDATE_AGID: - length = 0; - break; - default: - return EINVAL; - } - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_REPORT_KEY; - ccb[2] = (lba >> 24) & 0xff; - ccb[3] = (lba >> 16) & 0xff; - ccb[4] = (lba >> 8) & 0xff; - ccb[5] = lba & 0xff; - ccb[8] = (length >> 8) & 0xff; - ccb[9] = length & 0xff; - ccb[10] = (ai->agid << 6) | ai->format; - - if (length) { - if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO))) - return ENOMEM; - d->length = htons(length - 2); - } - - error = ata_atapicmd(dev, ccb, (caddr_t)d, length, - ai->format == DVD_INVALIDATE_AGID ? 0 : ATA_R_READ,10); - if (error) { - if (length) - free(d, M_ACD); - return error; - } - - switch (ai->format) { - case DVD_REPORT_AGID: - ai->agid = d->data[3] >> 6; - break; - - case DVD_REPORT_CHALLENGE: - bcopy(&d->data[0], &ai->keychal[0], 10); - break; - - case DVD_REPORT_KEY1: - bcopy(&d->data[0], &ai->keychal[0], 5); - break; - - case DVD_REPORT_TITLE_KEY: - ai->cpm = (d->data[0] >> 7); - ai->cp_sec = (d->data[0] >> 6) & 0x1; - ai->cgms = (d->data[0] >> 4) & 0x3; - bcopy(&d->data[1], &ai->keychal[0], 5); - break; - - case DVD_REPORT_ASF: - ai->asf = d->data[3] & 1; - break; - - case DVD_REPORT_RPC: - ai->reg_type = (d->data[0] >> 6); - ai->vend_rsts = (d->data[0] >> 3) & 0x7; - ai->user_rsts = d->data[0] & 0x7; - ai->region = d->data[1]; - ai->rpc_scheme = d->data[2]; - break; - - case DVD_INVALIDATE_AGID: - break; - - default: - error = EINVAL; - } - if (length) - free(d, M_ACD); - return error; -} - -static int -acd_send_key(device_t dev, struct dvd_authinfo *ai) -{ - struct dvd_miscauth *d; - int16_t length; - int8_t ccb[16]; - int error; - - switch (ai->format) { - case DVD_SEND_CHALLENGE: - length = 16; - if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO))) - return ENOMEM; - bcopy(ai->keychal, &d->data[0], 10); - break; - - case DVD_SEND_KEY2: - length = 12; - if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO))) - return ENOMEM; - bcopy(&ai->keychal[0], &d->data[0], 5); - break; - - case DVD_SEND_RPC: - length = 8; - if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO))) - return ENOMEM; - d->data[0] = ai->region; - break; - - default: - return EINVAL; - } - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_SEND_KEY; - ccb[8] = (length >> 8) & 0xff; - ccb[9] = length & 0xff; - ccb[10] = (ai->agid << 6) | ai->format; - d->length = htons(length - 2); - error = ata_atapicmd(dev, ccb, (caddr_t)d, length, 0, 10); - free(d, M_ACD); - return error; -} - -static int -acd_read_structure(device_t dev, struct dvd_struct *s) -{ - struct dvd_miscauth *d; - u_int16_t length; - int8_t ccb[16]; - int error = 0; - - switch(s->format) { - case DVD_STRUCT_PHYSICAL: - length = 21; - break; - - case DVD_STRUCT_COPYRIGHT: - length = 8; - break; - - case DVD_STRUCT_DISCKEY: - length = 2052; - break; - - case DVD_STRUCT_BCA: - length = 192; - break; - - case DVD_STRUCT_MANUFACT: - length = 2052; - break; - - case DVD_STRUCT_DDS: - case DVD_STRUCT_PRERECORDED: - case DVD_STRUCT_UNIQUEID: - case DVD_STRUCT_LIST: - case DVD_STRUCT_CMI: - case DVD_STRUCT_RMD_LAST: - case DVD_STRUCT_RMD_RMA: - case DVD_STRUCT_DCB: - return ENOSYS; - - default: - return EINVAL; - } - - if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO))) - return ENOMEM; - d->length = htons(length - 2); - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_READ_STRUCTURE; - ccb[6] = s->layer_num; - ccb[7] = s->format; - ccb[8] = (length >> 8) & 0xff; - ccb[9] = length & 0xff; - ccb[10] = s->agid << 6; - error = ata_atapicmd(dev, ccb, (caddr_t)d, length, ATA_R_READ, 30); - if (error) { - free(d, M_ACD); - return error; - } - - switch (s->format) { - case DVD_STRUCT_PHYSICAL: { - struct dvd_layer *layer = (struct dvd_layer *)&s->data[0]; - - layer->book_type = d->data[0] >> 4; - layer->book_version = d->data[0] & 0xf; - layer->disc_size = d->data[1] >> 4; - layer->max_rate = d->data[1] & 0xf; - layer->nlayers = (d->data[2] >> 5) & 3; - layer->track_path = (d->data[2] >> 4) & 1; - layer->layer_type = d->data[2] & 0xf; - layer->linear_density = d->data[3] >> 4; - layer->track_density = d->data[3] & 0xf; - layer->start_sector = d->data[5] << 16 | d->data[6] << 8 | d->data[7]; - layer->end_sector = d->data[9] << 16 | d->data[10] << 8 | d->data[11]; - layer->end_sector_l0 = d->data[13] << 16 | d->data[14] << 8|d->data[15]; - layer->bca = d->data[16] >> 7; - break; - } - - case DVD_STRUCT_COPYRIGHT: - s->cpst = d->data[0]; - s->rmi = d->data[1]; - break; - - case DVD_STRUCT_DISCKEY: - bcopy(&d->data[0], &s->data[0], 2048); - break; - - case DVD_STRUCT_BCA: - s->length = ntohs(d->length); - bcopy(&d->data[0], &s->data[0], s->length); - break; - - case DVD_STRUCT_MANUFACT: - s->length = ntohs(d->length); - bcopy(&d->data[0], &s->data[0], s->length); - break; - - default: - error = EINVAL; - } - free(d, M_ACD); - return error; -} - -static int -acd_tray(device_t dev, int close) -{ - struct ata_device *atadev = device_get_softc(dev); - struct acd_softc *cdp = device_get_ivars(dev); - int error = ENODEV; - - if (cdp->cap.mechanism & MST_EJECT) { - if (close) { - if (!(error = acd_start_stop(dev, 3))) { - acd_read_toc(dev); - acd_prevent_allow(dev, 1); - cdp->flags |= F_LOCKED; - } - } - else { - acd_start_stop(dev, 0); - acd_prevent_allow(dev, 0); - cdp->flags &= ~F_LOCKED; - atadev->flags |= ATA_D_MEDIA_CHANGED; - error = acd_start_stop(dev, 2); - } - } - return error; -} - -static int -acd_blank(device_t dev, int blanktype) -{ - struct ata_device *atadev = device_get_softc(dev); - int8_t ccb[16] = { ATAPI_BLANK, 0x10 | (blanktype & 0x7), 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - - atadev->flags |= ATA_D_MEDIA_CHANGED; - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -acd_prevent_allow(device_t dev, int lock) -{ - int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -acd_start_stop(device_t dev, int start) -{ - int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -acd_pause_resume(device_t dev, int pause) -{ - int8_t ccb[16] = { ATAPI_PAUSE, 0, 0, 0, 0, 0, 0, 0, pause, - 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -acd_mode_sense(device_t dev, int page, caddr_t pagebuf, int pagesize) -{ - int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, page, 0, 0, 0, 0, - pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, pagebuf, pagesize, ATA_R_READ, 10); - return error; -} - -static int -acd_mode_select(device_t dev, caddr_t pagebuf, int pagesize) -{ - int8_t ccb[16] = { ATAPI_MODE_SELECT_BIG, 0x10, 0, 0, 0, 0, 0, - pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, pagebuf, pagesize, 0, 30); -} - -static int -acd_set_speed(device_t dev, int rdspeed, int wrspeed) -{ - int8_t ccb[16] = { ATAPI_SET_SPEED, 0, rdspeed >> 8, rdspeed, - wrspeed >> 8, wrspeed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 30); - if (!error) - acd_get_cap(dev); - return error; -} - -static void -acd_get_cap(device_t dev) -{ - struct acd_softc *cdp = device_get_ivars(dev); - int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, ATAPI_CDROM_CAP_PAGE, - 0, 0, 0, 0, sizeof(cdp->cap)>>8, sizeof(cdp->cap), - 0, 0, 0, 0, 0, 0, 0 }; - int count; - - /* get drive capabilities, some bugridden drives needs this repeated */ - for (count = 0 ; count < 5 ; count++) { - if (!ata_atapicmd(dev, ccb, (caddr_t)&cdp->cap, sizeof(cdp->cap), - ATA_R_READ | ATA_R_QUIET, 5)) { - cdp->cap.data_length = ntohs(cdp->cap.data_length); - cdp->cap.blk_desc_len = ntohs(cdp->cap.blk_desc_len); - cdp->cap.media = ntohs(cdp->cap.media); - cdp->cap.capabilities = ntohs(cdp->cap.capabilities); - cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed); - cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels); - cdp->cap.buf_size = ntohs(cdp->cap.buf_size); - cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed); - cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed); - cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed),177); - cdp->cap.copy_protect_rev = ntohs(cdp->cap.copy_protect_rev); - } - } -} - -static int -acd_read_format_caps(device_t dev, struct cdr_format_capacities *caps) -{ - int8_t ccb[16] = { ATAPI_READ_FORMAT_CAPACITIES, 0, 0, 0, 0, 0, 0, - (sizeof(struct cdr_format_capacities) >> 8) & 0xff, - sizeof(struct cdr_format_capacities) & 0xff, - 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, (caddr_t)caps, - sizeof(struct cdr_format_capacities), ATA_R_READ, 30); -} - -static int -acd_format(device_t dev, struct cdr_format_params* params) -{ - int8_t ccb[16] = { ATAPI_FORMAT, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, (u_int8_t *)params, - sizeof(struct cdr_format_params), 0, 30); - return error; -} - -static int -acd_test_ready(device_t dev) -{ - int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static void -acd_describe(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct acd_softc *cdp = device_get_ivars(dev); - int comma = 0; - char *mechanism; - - if (bootverbose) { - device_printf(dev, "<%.40s/%.8s> %s drive at ata%d as %s\n", - atadev->param.model, atadev->param.revision, - (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" : - (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" : - (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" : - (cdp->cap.media & MST_WRITE_CDR) ? "CDR" : - (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM":"CDROM", - device_get_unit(ch->dev), ata_unit2str(atadev)); - - device_printf(dev, "%s", ""); - if (cdp->cap.cur_read_speed) { - printf("read %dKB/s", cdp->cap.cur_read_speed * 1000 / 1024); - if (cdp->cap.max_read_speed) - printf(" (%dKB/s)", cdp->cap.max_read_speed * 1000 / 1024); - if ((cdp->cap.cur_write_speed) && - (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW | - MST_WRITE_DVDR | MST_WRITE_DVDRAM))) { - printf(" write %dKB/s", cdp->cap.cur_write_speed * 1000 / 1024); - if (cdp->cap.max_write_speed) - printf(" (%dKB/s)", cdp->cap.max_write_speed * 1000 / 1024); - } - comma = 1; - } - if (cdp->cap.buf_size) { - printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size); - comma = 1; - } - printf("%s %s %s\n", comma ? "," : "", ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - - device_printf(dev, "Reads:"); - comma = 0; - if (cdp->cap.media & MST_READ_CDR) { - printf(" CDR"); comma = 1; - } - if (cdp->cap.media & MST_READ_CDRW) { - printf("%s CDRW", comma ? "," : ""); comma = 1; - } - if (cdp->cap.capabilities & MST_READ_CDDA) { - if (cdp->cap.capabilities & MST_CDDA_STREAM) - printf("%s CDDA stream", comma ? "," : ""); - else - printf("%s CDDA", comma ? "," : ""); - comma = 1; - } - if (cdp->cap.media & MST_READ_DVDROM) { - printf("%s DVDROM", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_READ_DVDR) { - printf("%s DVDR", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_READ_DVDRAM) { - printf("%s DVDRAM", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_READ_PACKET) - printf("%s packet", comma ? "," : ""); - - printf("\n"); - device_printf(dev, "Writes:"); - if (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW | - MST_WRITE_DVDR | MST_WRITE_DVDRAM)) { - comma = 0; - if (cdp->cap.media & MST_WRITE_CDR) { - printf(" CDR" ); comma = 1; - } - if (cdp->cap.media & MST_WRITE_CDRW) { - printf("%s CDRW", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_WRITE_DVDR) { - printf("%s DVDR", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_WRITE_DVDRAM) { - printf("%s DVDRAM", comma ? "," : ""); comma = 1; - } - if (cdp->cap.media & MST_WRITE_TEST) { - printf("%s test write", comma ? "," : ""); comma = 1; - } - if (cdp->cap.capabilities & MST_BURNPROOF) - printf("%s burnproof", comma ? "," : ""); - } - printf("\n"); - if (cdp->cap.capabilities & MST_AUDIO_PLAY) { - device_printf(dev, "Audio: "); - if (cdp->cap.capabilities & MST_AUDIO_PLAY) - printf("play"); - if (cdp->cap.max_vol_levels) - printf(", %d volume levels", cdp->cap.max_vol_levels); - printf("\n"); - } - device_printf(dev, "Mechanism: "); - switch (cdp->cap.mechanism & MST_MECH_MASK) { - case MST_MECH_CADDY: - mechanism = "caddy"; break; - case MST_MECH_TRAY: - mechanism = "tray"; break; - case MST_MECH_POPUP: - mechanism = "popup"; break; - case MST_MECH_CHANGER: - mechanism = "changer"; break; - case MST_MECH_CARTRIDGE: - mechanism = "cartridge"; break; - default: - mechanism = 0; break; - } - if (mechanism) - printf("%s%s", (cdp->cap.mechanism & MST_EJECT) ? - "ejectable " : "", mechanism); - else if (cdp->cap.mechanism & MST_EJECT) - printf("ejectable"); - - if (cdp->cap.mechanism & MST_LOCKABLE) - printf((cdp->cap.mechanism & MST_LOCKED) ? ", locked":", unlocked"); - if (cdp->cap.mechanism & MST_PREVENT) - printf(", lock protected"); - printf("\n"); - - if ((cdp->cap.mechanism & MST_MECH_MASK) != MST_MECH_CHANGER) { - device_printf(dev, "Medium: "); - switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) { - case MST_CDROM: - printf("CD-ROM "); break; - case MST_CDR: - printf("CD-R "); break; - case MST_CDRW: - printf("CD-RW "); break; - case MST_DVD: - printf("DVD "); break; - case MST_DOOR_OPEN: - printf("door open"); break; - case MST_NO_DISC: - printf("no/blank disc"); break; - case MST_FMT_ERROR: - printf("medium format error"); break; - } - if ((cdp->cap.medium_type & MST_TYPE_MASK_HIGH)cap.medium_type & MST_TYPE_MASK_LOW) { - case MST_DATA_120: - printf("120mm data disc"); break; - case MST_AUDIO_120: - printf("120mm audio disc"); break; - case MST_COMB_120: - printf("120mm data/audio disc"); break; - case MST_PHOTO_120: - printf("120mm photo disc"); break; - case MST_DATA_80: - printf("80mm data disc"); break; - case MST_AUDIO_80: - printf("80mm audio disc"); break; - case MST_COMB_80: - printf("80mm data/audio disc"); break; - case MST_PHOTO_80: - printf("80mm photo disc"); break; - case MST_FMT_NONE: - switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) { - case MST_CDROM: - printf("unknown"); break; - case MST_CDR: - case MST_CDRW: - printf("blank"); break; - } - break; - default: - printf("unknown (0x%x)", cdp->cap.medium_type); break; - } - } - printf("\n"); - } - } - else { - device_printf(dev, "%s ", - (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" : - (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" : - (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" : - (cdp->cap.media & MST_WRITE_CDR) ? "CDR" : - (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM" : - "CDROM"); - if (cdp->changer_info) - printf("with %d CD changer ", cdp->changer_info->slots); - printf("<%.40s/%.8s> at ata%d-%s %s %s\n", - atadev->param.model, atadev->param.revision, - device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - } -} - -static device_method_t acd_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, acd_probe), - DEVMETHOD(device_attach, acd_attach), - DEVMETHOD(device_detach, acd_detach), - DEVMETHOD(device_shutdown, acd_shutdown), - - /* ATA methods */ - DEVMETHOD(ata_reinit, acd_reinit), - - DEVMETHOD_END -}; - -static driver_t acd_driver = { - "acd", - acd_methods, - 0, -}; - -static devclass_t acd_devclass; - -static int -acd_modevent(module_t mod, int what, void *arg) -{ - return g_modevent(0, what, &acd_class); -} - -DRIVER_MODULE(acd, ata, acd_driver, acd_devclass, acd_modevent, NULL); -MODULE_VERSION(acd, 1); -MODULE_DEPEND(acd, ata, 1, 1, 1); diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h deleted file mode 100644 index 33713aa..0000000 --- a/sys/dev/ata/atapi-cd.h +++ /dev/null @@ -1,315 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* CDROM Table Of Contents */ -#define MAXTRK 99 -struct toc { - struct ioc_toc_header hdr; - struct cd_toc_entry tab[MAXTRK + 1]; -}; - -/* DVD CSS authentication */ -struct dvd_miscauth { - u_int16_t length; - u_int16_t reserved; - u_int8_t data[2048]; -}; - -/* CDROM Audio Control Parameters Page */ -struct audiopage { - /* mode page data header */ - u_int16_t data_length; - u_int8_t medium_type; - u_int8_t dev_spec; - u_int8_t unused[2]; - u_int16_t blk_desc_len; - - /* audio control page */ - u_int8_t page_code; -#define ATAPI_CDROM_AUDIO_PAGE 0x0e -#define ATAPI_CDROM_AUDIO_PAGE_MASK 0x4e - - u_int8_t param_len; - u_int8_t flags; -#define CD_PA_SOTC 0x02 -#define CD_PA_IMMED 0x04 - - u_int8_t reserved3; - u_int8_t reserved4; - u_int8_t reserved5; - u_int16_t lb_per_sec; - struct port_control { - u_int8_t channels:4; -#define CHANNEL_0 1 -#define CHANNEL_1 2 -#define CHANNEL_2 4 -#define CHANNEL_3 8 - - u_int8_t volume; - } port[4]; -}; - - -/* CDROM Capabilities and Mechanical Status Page */ -struct cappage { - /* mode page data header */ - u_int16_t data_length; - u_int8_t medium_type; -#define MST_TYPE_MASK_LOW 0x0f -#define MST_FMT_NONE 0x00 -#define MST_DATA_120 0x01 -#define MST_AUDIO_120 0x02 -#define MST_COMB_120 0x03 -#define MST_PHOTO_120 0x04 -#define MST_DATA_80 0x05 -#define MST_AUDIO_80 0x06 -#define MST_COMB_80 0x07 -#define MST_PHOTO_80 0x08 - -#define MST_TYPE_MASK_HIGH 0x70 -#define MST_CDROM 0x00 -#define MST_CDR 0x10 -#define MST_CDRW 0x20 -#define MST_DVD 0x40 - -#define MST_NO_DISC 0x70 -#define MST_DOOR_OPEN 0x71 -#define MST_FMT_ERROR 0x72 - - u_int8_t dev_spec; - u_int16_t unused; - u_int16_t blk_desc_len; - - /* capabilities page */ - u_int8_t page_code; -#define ATAPI_CDROM_CAP_PAGE 0x2a - - u_int8_t param_len; - - u_int16_t media; -#define MST_READ_CDR 0x0100 -#define MST_READ_CDRW 0x0200 -#define MST_READ_PACKET 0x0400 -#define MST_READ_DVDROM 0x0800 -#define MST_READ_DVDR 0x1000 -#define MST_READ_DVDRAM 0x2000 -#define MST_WRITE_CDR 0x0001 -#define MST_WRITE_CDRW 0x0002 -#define MST_WRITE_TEST 0x0004 -#define MST_WRITE_DVDR 0x0010 -#define MST_WRITE_DVDRAM 0x0020 - - u_int16_t capabilities; -#define MST_AUDIO_PLAY 0x0100 -#define MST_COMPOSITE 0x0200 -#define MST_AUDIO_P1 0x0400 -#define MST_AUDIO_P2 0x0800 -#define MST_MODE2_f1 0x1000 -#define MST_MODE2_f2 0x2000 -#define MST_MULTISESSION 0x4000 -#define MST_BURNPROOF 0x8000 -#define MST_READ_CDDA 0x0001 -#define MST_CDDA_STREAM 0x0002 -#define MST_COMBINED_RW 0x0004 -#define MST_CORRECTED_RW 0x0008 -#define MST_SUPPORT_C2 0x0010 -#define MST_ISRC 0x0020 -#define MST_UPC 0x0040 - - u_int8_t mechanism; -#define MST_LOCKABLE 0x01 -#define MST_LOCKED 0x02 -#define MST_PREVENT 0x04 -#define MST_EJECT 0x08 -#define MST_MECH_MASK 0xe0 -#define MST_MECH_CADDY 0x00 -#define MST_MECH_TRAY 0x20 -#define MST_MECH_POPUP 0x40 -#define MST_MECH_CHANGER 0x80 -#define MST_MECH_CARTRIDGE 0xa0 - - uint8_t audio; -#define MST_SEP_VOL 0x01 -#define MST_SEP_MUTE 0x02 - - u_int16_t max_read_speed; /* max raw data rate in bytes/1000 */ - u_int16_t max_vol_levels; /* number of discrete volume levels */ - u_int16_t buf_size; /* internal buffer size in bytes/1024 */ - u_int16_t cur_read_speed; /* current data rate in bytes/1000 */ - - u_int8_t reserved3; - u_int8_t misc; - - u_int16_t max_write_speed; /* max raw data rate in bytes/1000 */ - u_int16_t cur_write_speed; /* current data rate in bytes/1000 */ - u_int16_t copy_protect_rev; - u_int16_t reserved4; -}; - -#define CH_READY 0 -#define CH_LOADING 1 -#define CH_UNLOADING 2 -#define CH_INITIALIZING 3 - -#define CD_IDLE 0 -#define CD_AUDIO_ACTIVE 1 -#define CD_AUDIO_SCAN 2 -#define CD_HOST_ACTIVE 3 -#define CD_NO_STATE 7 - -/* CDROM Changer mechanism status structure */ -struct changer { - u_int8_t current_slot :5; /* active changer slot */ - u_int8_t mech_state :2; /* current changer state */ - - u_int8_t fault :1; /* fault in last operation */ - u_int8_t reserved0 :5; - u_int8_t cd_state :3; /* current mechanism state */ - - u_int8_t current_lba[3]; /* current LBA */ - u_int8_t slots; /* number of available slots */ - u_int16_t table_length; /* slot table length */ - struct { - u_int8_t changed :1; /* media has changed in this slot */ - u_int8_t unused :6; - u_int8_t present :1; /* slot has a CD present */ - u_int8_t reserved0; - u_int8_t reserved1; - u_int8_t reserved2; - } slot[32]; -}; - -/* CDROM Write Parameters Mode Page (Burners ONLY) */ -struct write_param { - /* mode page data header */ - u_int16_t data_length; - u_int8_t medium_type; - u_int8_t dev_spec; - u_int8_t unused[2]; - u_int16_t blk_desc_len; - - /* write parameters page */ - u_int8_t page_code; -#define ATAPI_CDROM_WRITE_PARAMETERS_PAGE 0x05 - - u_int8_t page_length; /* 0x32 */ - u_int8_t write_type :4; /* write stream type */ -#define CDR_WTYPE_PACKET 0x00 -#define CDR_WTYPE_TRACK 0x01 -#define CDR_WTYPE_SESSION 0x02 -#define CDR_WTYPE_RAW 0x03 - - u_int8_t test_write :1; /* test write enable */ - u_int8_t link_size_valid :1; - u_int8_t burnproof :1; /* BurnProof enable */ - u_int8_t reserved2_7 :1; - u_int8_t track_mode :4; /* track mode */ -#define CDR_TMODE_AUDIO 0x00 -#define CDR_TMODE_AUDIO_PREEMP 0x01 -#define CDR_TMODE_ALLOW_COPY 0x02 -#define CDR_TMODE_DATA 0x04 -#define CDR_TMODE_QUAD_AUDIO 0x08 - - u_int8_t copy :1; /* generation stamp */ - u_int8_t fp :1; /* fixed packet type */ - u_int8_t session_type :2; /* session type */ -#define CDR_SESS_NONE 0x00 -#define CDR_SESS_FINAL 0x01 -#define CDR_SESS_RESERVED 0x02 -#define CDR_SESS_MULTI 0x03 - - u_int8_t datablock_type :4; /* data type code (see cdrio.h) */ - u_int8_t reserved4_4567 :4; - u_int8_t link_size; - u_int8_t reserved6; - u_int8_t host_app_code :6; /* host application code */ - u_int8_t reserved7_67 :2; - u_int8_t session_format; /* session format */ -#define CDR_SESS_CDROM 0x00 -#define CDR_SESS_CDI 0x10 -#define CDR_SESS_CDROM_XA 0x20 - - u_int8_t reserved9; - u_int32_t packet_size; /* packet size in bytes */ - u_int16_t audio_pause_length; /* audio pause length in secs */ - u_int8_t media_catalog_number[16]; - u_int8_t isr_code[16]; - u_int8_t sub_hdr_byte0; - u_int8_t sub_hdr_byte1; - u_int8_t sub_hdr_byte2; - u_int8_t sub_hdr_byte3; - u_int8_t vendor_specific_byte0; - u_int8_t vendor_specific_byte1; - u_int8_t vendor_specific_byte2; - u_int8_t vendor_specific_byte3; -} __packed; - -/* CDROM Read Track Information structure */ -struct acd_track_info { - u_int16_t data_length; - u_int8_t track_number; /* current track number */ - u_int8_t session_number; /* current session number */ - u_int8_t reserved4; - u_int8_t track_mode :4; /* mode of this track */ - u_int8_t copy :1; /* generation stamp */ - u_int8_t damage :1; /* damaged track */ - u_int8_t reserved5_67 :2; - u_int8_t data_mode :4; /* data mode of this disc */ - u_int8_t fp :1; /* fixed packet */ - u_int8_t packet :1; /* packet track */ - u_int8_t blank :1; /* blank (empty) track */ - u_int8_t rt :1; /* reserved track */ - u_int8_t nwa_valid :1; /* next_writeable_addr field valid */ - u_int8_t reserved7_17 :7; - u_int track_start_addr; /* start of this track */ - u_int next_writeable_addr; /* next writeable addr on this disc */ - u_int free_blocks; /* free block on this disc */ - u_int fixed_packet_size; /* size of packets on this track */ - u_int track_length; /* length of this track */ -}; - -/* Structure describing an ATAPI CDROM device */ -struct acd_softc { - int flags; /* device state flags */ -#define F_LOCKED 0x0001 /* this unit is locked */ - - struct toc toc; /* table of disc contents */ - struct audiopage au; /* audio page info */ - struct audiopage aumask; /* audio page mask */ - struct cappage cap; /* capabilities page info */ - struct cd_sub_channel_info subchan; /* subchannel info */ - struct changer *changer_info; /* changer info */ - struct acd_softc **driver; /* softc's of changer slots */ - int slot; /* this instance slot number */ - time_t timestamp; /* this instance timestamp */ - u_int32_t disk_size; /* size of current media */ - u_int32_t block_size; /* blocksize currently used */ - u_int32_t iomax; /* Max I/O request (bytes) */ - struct g_geom *gp; /* geom instance */ - struct g_provider *pp[MAXTRK+1]; /* providers */ -}; diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c deleted file mode 100644 index 403abe0..0000000 --- a/sys/dev/ata/atapi-fd.c +++ /dev/null @@ -1,440 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* prototypes */ -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 *); -static int afd_prevent_allow(device_t, int); -static int afd_test_ready(device_t); - -/* internal vars */ -static MALLOC_DEFINE(M_AFD, "afd_driver", "ATAPI floppy driver buffers"); - -static int -afd_probe(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - if ((atadev->param.config & ATA_PROTO_ATAPI) && - (atadev->param.config & ATA_ATAPI_TYPE_MASK) == ATA_ATAPI_TYPE_DIRECT) - return 0; - else - return ENXIO; -} - -static int -afd_attach(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct afd_softc *fdp; - - if (!(fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO))) { - device_printf(dev, "out of memory\n"); - return ENOMEM; - } - device_set_ivars(dev, fdp); - ata_setmode(dev); - - if (afd_sense(dev)) { - device_set_ivars(dev, NULL); - free(fdp, M_AFD); - return ENXIO; - } - atadev->flags |= ATA_D_MEDIA_CHANGED; - - /* announce we are here */ - afd_describe(dev); - - /* create the disk device */ - fdp->disk = disk_alloc(); - 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; - fdp->disk->d_maxsize = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; - fdp->disk->d_unit = device_get_unit(dev); - disk_create(fdp->disk, DISK_VERSION); - return 0; -} - -static int -afd_detach(device_t dev) -{ - struct afd_softc *fdp = device_get_ivars(dev); - - /* check that we have a valid device to detach */ - if (!device_get_ivars(dev)) - return ENXIO; - - /* detroy disk from the system so we dont get any further requests */ - disk_destroy(fdp->disk); - - /* fail requests on the queue and any thats "in flight" for this device */ - ata_fail_requests(dev); - - /* dont leave anything behind */ - device_set_ivars(dev, NULL); - free(fdp, M_AFD); - return 0; -} - -static int -afd_shutdown(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); - return 0; -} - -static int -afd_reinit(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - - /* if detach pending, return error */ - if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) - return 1; - - ata_setmode(dev); - return 0; -} - -static int -afd_open(struct disk *dp) -{ - device_t dev = dp->d_drv1; - struct ata_device *atadev = device_get_softc(dev); - struct afd_softc *fdp = device_get_ivars(dev); - - if (!fdp) - return ENXIO; - if (!device_is_attached(dev)) - return EBUSY; - - afd_test_ready(dev); - afd_prevent_allow(dev, 1); - - if (afd_sense(dev)) - device_printf(dev, "sense media type failed\n"); - atadev->flags &= ~ATA_D_MEDIA_CHANGED; - - if (!fdp->mediasize) - return ENXIO; - - fdp->disk->d_sectorsize = fdp->sectorsize; - fdp->disk->d_mediasize = fdp->mediasize; - fdp->disk->d_fwsectors = fdp->sectors; - fdp->disk->d_fwheads = fdp->heads; - return 0; -} - -static int -afd_close(struct disk *dp) -{ - device_t dev = dp->d_drv1; - - afd_prevent_allow(dev, 0); - return 0; -} - -static void -afd_strategy(struct bio *bp) -{ - device_t dev = bp->bio_disk->d_drv1; - struct ata_device *atadev = device_get_softc(dev); - struct afd_softc *fdp = device_get_ivars(dev); - struct ata_request *request; - u_int16_t count; - int8_t ccb[16]; - - /* if it's a null transfer, return immediatly. */ - if (bp->bio_bcount == 0) { - bp->bio_resid = 0; - biodone(bp); - return; - } - - /* should reject all queued entries if media have changed. */ - if (atadev->flags & ATA_D_MEDIA_CHANGED) { - biofinish(bp, NULL, EIO); - return; - } - - count = bp->bio_bcount / fdp->sectorsize; - bp->bio_resid = bp->bio_bcount; - - bzero(ccb, sizeof(ccb)); - - if (bp->bio_cmd == BIO_READ) - ccb[0] = ATAPI_READ_BIG; - else - ccb[0] = ATAPI_WRITE_BIG; - - ccb[2] = bp->bio_pblkno >> 24; - ccb[3] = bp->bio_pblkno >> 16; - ccb[4] = bp->bio_pblkno >> 8; - ccb[5] = bp->bio_pblkno; - ccb[7] = count>>8; - ccb[8] = count; - - if (!(request = ata_alloc_request())) { - biofinish(bp, NULL, ENOMEM); - return; - } - request->dev = dev; - request->bio = bp; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = bp->bio_data; - request->bytecount = count * fdp->sectorsize; - request->transfersize = min(request->bytecount, 65534); - request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30; - request->retries = 2; - request->callback = afd_done; - switch (bp->bio_cmd) { - case BIO_READ: - request->flags = (ATA_R_ATAPI | ATA_R_READ); - break; - case BIO_WRITE: - request->flags = (ATA_R_ATAPI | ATA_R_WRITE); - break; - default: - device_printf(dev, "unknown BIO operation\n"); - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - if (atadev->mode >= ATA_DMA) - request->flags |= ATA_R_DMA; - request->flags |= ATA_R_ORDERED; - ata_queue_request(request); -} - -static void -afd_done(struct ata_request *request) -{ - struct bio *bp = request->bio; - - /* finish up transfer */ - if ((bp->bio_error = request->result)) - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount - request->donecount; - biodone(bp); - 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) -{ - struct ata_device *atadev = device_get_softc(dev); - struct afd_softc *fdp = device_get_ivars(dev); - struct afd_capacity capacity; - struct afd_capacity_big capacity_big; - struct afd_capabilities capabilities; - int8_t ccb1[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int8_t ccb2[16] = { ATAPI_SERVICE_ACTION_IN, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, sizeof(struct afd_capacity_big) & 0xff, 0, 0 }; - int8_t ccb3[16] = { ATAPI_MODE_SENSE_BIG, 0, ATAPI_REWRITEABLE_CAP_PAGE, - 0, 0, 0, 0, sizeof(struct afd_capabilities) >> 8, - sizeof(struct afd_capabilities) & 0xff, - 0, 0, 0, 0, 0, 0, 0 }; - int timeout = 20; - int error, count; - - fdp->mediasize = 0; - - /* wait for device to get ready */ - while ((error = afd_test_ready(dev)) && timeout--) { - DELAY(100000); - } - if (error == EBUSY) - return 1; - - /* The IOMEGA Clik! doesn't support reading the cap page, fake it */ - if (!strncmp(atadev->param.model, "IOMEGA Clik!", 12)) { - fdp->heads = 1; - fdp->sectors = 2; - fdp->mediasize = 39441 * 1024; - fdp->sectorsize = 512; - afd_test_ready(dev); - return 0; - } - - /* get drive capacity */ - if (!ata_atapicmd(dev, ccb1, (caddr_t)&capacity, - sizeof(struct afd_capacity), ATA_R_READ, 30)) { - fdp->heads = 16; - fdp->sectors = 63; - fdp->sectorsize = be32toh(capacity.blocksize); - fdp->mediasize = (u_int64_t)be32toh(capacity.capacity)*fdp->sectorsize; - afd_test_ready(dev); - return 0; - } - - /* get drive capacity big */ - if (!ata_atapicmd(dev, ccb2, (caddr_t)&capacity_big, - sizeof(struct afd_capacity_big), - ATA_R_READ | ATA_R_QUIET, 30)) { - fdp->heads = 16; - fdp->sectors = 63; - fdp->sectorsize = be32toh(capacity_big.blocksize); - fdp->mediasize = be64toh(capacity_big.capacity)*fdp->sectorsize; - afd_test_ready(dev); - return 0; - } - - /* get drive capabilities, some bugridden drives needs this repeated */ - for (count = 0 ; count < 5 ; count++) { - if (!ata_atapicmd(dev, ccb3, (caddr_t)&capabilities, - sizeof(struct afd_capabilities), ATA_R_READ, 30) && - capabilities.page_code == ATAPI_REWRITEABLE_CAP_PAGE) { - fdp->heads = capabilities.heads; - fdp->sectors = capabilities.sectors; - fdp->sectorsize = be16toh(capabilities.sector_size); - fdp->mediasize = be16toh(capabilities.cylinders) * - fdp->heads * fdp->sectors * fdp->sectorsize; - if (!capabilities.medium_type) - fdp->mediasize = 0; - return 0; - } - } - return 1; -} - -static int -afd_prevent_allow(device_t dev, int lock) -{ - struct ata_device *atadev = device_get_softc(dev); - int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - if (!strncmp(atadev->param.model, "IOMEGA Clik!", 12)) - return 0; - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -afd_test_ready(device_t dev) -{ - int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static void -afd_describe(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct afd_softc *fdp = device_get_ivars(dev); - char sizestring[16]; - - if (fdp->mediasize > 1048576 * 5) - sprintf(sizestring, "%juMB", fdp->mediasize / 1048576); - else if (fdp->mediasize) - sprintf(sizestring, "%juKB", fdp->mediasize / 1024); - else - strcpy(sizestring, "(no media)"); - - device_printf(dev, "%s <%.40s %.8s> at ata%d-%s %s %s\n", - sizestring, atadev->param.model, atadev->param.revision, - device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - if (bootverbose) { - device_printf(dev, "%ju sectors [%juC/%dH/%dS]\n", - fdp->mediasize / fdp->sectorsize, - fdp->mediasize /(fdp->sectorsize*fdp->sectors*fdp->heads), - fdp->heads, fdp->sectors); - } -} - -static device_method_t afd_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, afd_probe), - DEVMETHOD(device_attach, afd_attach), - DEVMETHOD(device_detach, afd_detach), - DEVMETHOD(device_shutdown, afd_shutdown), - - /* ATA methods */ - DEVMETHOD(ata_reinit, afd_reinit), - - DEVMETHOD_END -}; - -static driver_t afd_driver = { - "afd", - afd_methods, - 0, -}; - -static devclass_t afd_devclass; - -DRIVER_MODULE(afd, ata, afd_driver, afd_devclass, NULL, NULL); -MODULE_VERSION(afd, 1); -MODULE_DEPEND(afd, ata, 1, 1, 1); - diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h deleted file mode 100644 index 5645698..0000000 --- a/sys/dev/ata/atapi-fd.h +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */ -struct afd_capabilities { - u_int16_t data_length; - u_int8_t medium_type; -#define MFD_2DD_UN 0x10 -#define MFD_2DD 0x11 -#define MFD_HD_UN 0x20 -#define MFD_HD_12_98 0x22 -#define MFD_HD_12 0x23 -#define MFD_HD_144 0x24 -#define MFD_UHD 0x31 - -#define MFD_UNKNOWN 0x00 -#define MFD_NO_DISC 0x70 -#define MFD_DOOR_OPEN 0x71 -#define MFD_FMT_ERROR 0x72 - - u_int8_t reserved0 :7; - u_int8_t wp :1; /* write protect */ - u_int8_t unused[4]; - - /* capabilities page */ - u_int8_t page_code :6; -#define ATAPI_REWRITEABLE_CAP_PAGE 0x05 - - u_int8_t reserved1_6 :1; - u_int8_t ps :1; /* page save supported */ - u_int8_t page_length; /* page length */ - u_int16_t transfer_rate; /* in kilobits per second */ - u_int8_t heads; /* number of heads */ - u_int8_t sectors; /* number of sectors pr track */ - u_int16_t sector_size; /* number of bytes per sector */ - u_int16_t cylinders; /* number of cylinders */ - u_int8_t reserved10[10]; - u_int8_t motor_delay; /* motor off delay */ - u_int8_t reserved21[7]; - u_int16_t rpm; /* rotations per minute */ - u_int8_t reserved30[2]; -}; - -struct afd_capacity { - u_int32_t capacity; - u_int32_t blocksize; -}; - -struct afd_capacity_big { - u_int64_t capacity; - u_int32_t blocksize; -}; - -struct afd_softc { - u_int64_t mediasize; - u_int32_t heads; - u_int32_t sectors; - u_int32_t sectorsize; - struct disk *disk; /* virtual drives */ -}; - diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c deleted file mode 100644 index 9f68a4b..0000000 --- a/sys/dev/ata/atapi-tape.c +++ /dev/null @@ -1,739 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ata.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* device structure */ -static d_open_t ast_open; -static d_close_t ast_close; -static d_ioctl_t ast_ioctl; -static d_strategy_t ast_strategy; -static struct cdevsw ast_cdevsw = { - .d_version = D_VERSION, - .d_open = ast_open, - .d_close = ast_close, - .d_read = physread, - .d_write = physwrite, - .d_ioctl = ast_ioctl, - .d_strategy = ast_strategy, - .d_name = "ast", - .d_flags = D_TAPE | D_TRACKCLOSE, -}; - -/* prototypes */ -static int ast_sense(device_t); -static void ast_describe(device_t); -static void ast_done(struct ata_request *); -static int ast_mode_sense(device_t, int, void *, int); -static int ast_mode_select(device_t, void *, int); -static int ast_write_filemark(device_t, u_int8_t); -static int ast_read_position(device_t, int, struct ast_readposition *); -static int ast_space(device_t, u_int8_t, int32_t); -static int ast_locate(device_t, int, u_int32_t); -static int ast_prevent_allow(device_t, int); -static int ast_load_unload(device_t, u_int8_t); -static int ast_rewind(device_t); -static int ast_erase(device_t); -static int ast_test_ready(device_t); -static int ast_wait_dsc(device_t, int); - -/* internal vars */ -static u_int64_t ast_total = 0; -static MALLOC_DEFINE(M_AST, "ast_driver", "ATAPI tape driver buffers"); - -static int -ast_probe(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if ((atadev->param.config & ATA_PROTO_ATAPI) && - (atadev->param.config & ATA_ATAPI_TYPE_MASK) == ATA_ATAPI_TYPE_TAPE) - return 0; - else - return ENXIO; -} - -static int -ast_attach(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct ast_softc *stp; - struct ast_readposition position; - struct cdev *device; - - if (!(stp = malloc(sizeof(struct ast_softc), M_AST, M_NOWAIT | M_ZERO))) { - device_printf(dev, "out of memory\n"); - return ENOMEM; - } - device_set_ivars(dev, stp); - ata_setmode(dev); - - if (ast_sense(dev)) { - device_set_ivars(dev, NULL); - free(stp, M_AST); - return ENXIO; - } - if (!strcmp(atadev->param.model, "OnStream DI-30")) { - struct ast_transferpage transfer; - struct ast_identifypage identify; - - stp->flags |= F_ONSTREAM; - bzero(&transfer, sizeof(struct ast_transferpage)); - ast_mode_sense(dev, ATAPI_TAPE_TRANSFER_PAGE, - &transfer, sizeof(transfer)); - bzero(&identify, sizeof(struct ast_identifypage)); - ast_mode_sense(dev, ATAPI_TAPE_IDENTIFY_PAGE, - &identify, sizeof(identify)); - strncpy(identify.ident, "FBSD", 4); - ast_mode_select(dev, &identify, sizeof(identify)); - ast_read_position(dev, 0, &position); - } - - stp->stats = devstat_new_entry("ast", device_get_unit(dev), DEV_BSIZE, - DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE, - DEVSTAT_PRIORITY_TAPE); - device = make_dev(&ast_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0640, - "ast%d", device_get_unit(dev)); - device->si_drv1 = dev; - device->si_iosize_max = ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS; - stp->dev1 = device; - device = make_dev(&ast_cdevsw, 1, UID_ROOT, GID_OPERATOR, 0640, - "nast%d", device_get_unit(dev)); - device->si_drv1 = dev; - device->si_iosize_max = ch->dma.max_iosize; - stp->dev2 = device; - - /* announce we are here and ready */ - ast_describe(dev); - return 0; -} - -static int -ast_detach(device_t dev) -{ - struct ast_softc *stp = device_get_ivars(dev); - - /* detroy devices from the system so we dont get any further requests */ - destroy_dev(stp->dev1); - destroy_dev(stp->dev2); - - /* fail requests on the queue and any thats "in flight" for this device */ - ata_fail_requests(dev); - - /* dont leave anything behind */ - devstat_remove_entry(stp->stats); - device_set_ivars(dev, NULL); - free(stp, M_AST); - return 0; -} - -static int -ast_shutdown(device_t dev) -{ - struct ata_device *atadev = device_get_softc(dev); - - if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) - ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0); - return 0; -} - -static int -ast_reinit(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - - /* if detach pending, return error */ - if (!(ch->devices & (ATA_ATAPI_MASTER << atadev->unit))) - return 1; - - ata_setmode(dev); - return 0; -} - -static int -ast_open(struct cdev *cdev, int flags, int fmt, struct thread *td) -{ - device_t dev = cdev->si_drv1; - struct ata_device *atadev = device_get_softc(dev); - struct ast_softc *stp = device_get_ivars(dev); - - if (!stp) - return ENXIO; - if (!device_is_attached(dev)) - return EBUSY; - - ast_test_ready(dev); - if (stp->cap.lock) - ast_prevent_allow(dev, 1); - if (ast_sense(dev)) - device_printf(dev, "sense media type failed\n"); - - atadev->flags &= ~ATA_D_MEDIA_CHANGED; - stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN); - ast_total = 0; - return 0; -} - -static int -ast_close(struct cdev *cdev, int flags, int fmt, struct thread *td) -{ - device_t dev = cdev->si_drv1; - struct ast_softc *stp = device_get_ivars(dev); - - /* flush buffers, some drives fail here, they should report ctl = 0 */ - if (stp->cap.ctl && (stp->flags & F_DATA_WRITTEN)) - ast_write_filemark(dev, 0); - - /* write filemark if data written to tape */ - if (!(stp->flags & F_ONSTREAM) && - (stp->flags & (F_DATA_WRITTEN | F_FM_WRITTEN)) == F_DATA_WRITTEN) - ast_write_filemark(dev, ATAPI_WF_WRITE); - - /* if unit is zero rewind on close */ - if (dev2unit(cdev) == 0) - ast_rewind(dev); - - if (stp->cap.lock && count_dev(cdev) == 1) - ast_prevent_allow(dev, 0); - - stp->flags &= ~F_CTL_WARN; -#ifdef AST_DEBUG - device_printf(dev, "%ju total bytes transferred\n", (uintmax_t)ast_total); -#endif - return 0; -} - -static int -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); - int error = 0; - - switch (cmd) { - case MTIOCGET: - { - struct mtget *g = (struct mtget *) data; - - bzero(g, sizeof(struct mtget)); - g->mt_type = 7; - g->mt_density = 1; - g->mt_blksiz = stp->blksize; - g->mt_comp = stp->cap.compress; - g->mt_density0 = 0; g->mt_density1 = 0; - g->mt_density2 = 0; g->mt_density3 = 0; - g->mt_blksiz0 = 0; g->mt_blksiz1 = 0; - g->mt_blksiz2 = 0; g->mt_blksiz3 = 0; - g->mt_comp0 = 0; g->mt_comp1 = 0; - g->mt_comp2 = 0; g->mt_comp3 = 0; - } - break; - - case MTIOCTOP: - { - int i; - struct mtop *mt = (struct mtop *)data; - - switch ((int16_t) (mt->mt_op)) { - - case MTWEOF: - for (i=0; i < mt->mt_count && !error; i++) - error = ast_write_filemark(dev, ATAPI_WF_WRITE); - break; - - case MTFSF: - if (mt->mt_count) - error = ast_space(dev, ATAPI_SP_FM, mt->mt_count); - break; - - case MTBSF: - if (mt->mt_count) - error = ast_space(dev, ATAPI_SP_FM, -(mt->mt_count)); - break; - - case MTREW: - error = ast_rewind(dev); - break; - - case MTOFFL: - error = ast_load_unload(dev, ATAPI_SS_EJECT); - break; - - case MTNOP: - error = ast_write_filemark(dev, 0); - break; - - case MTERASE: - error = ast_erase(dev); - break; - - case MTEOD: - error = ast_space(dev, ATAPI_SP_EOD, 0); - break; - - case MTRETENS: - error = ast_load_unload(dev, ATAPI_SS_RETENSION|ATAPI_SS_LOAD); - break; - - case MTFSR: - case MTBSR: - case MTCACHE: - case MTNOCACHE: - case MTSETBSIZ: - case MTSETDNSTY: - case MTCOMP: - default: - error = EINVAL; - } - } - break; - - case MTIOCRDSPOS: - { - struct ast_readposition position; - - if ((error = ast_read_position(dev, 0, &position))) - break; - *(u_int32_t *)data = position.tape; - } - break; - - case MTIOCRDHPOS: - { - struct ast_readposition position; - - if ((error = ast_read_position(dev, 1, &position))) - break; - *(u_int32_t *)data = position.tape; - } - break; - - case MTIOCSLOCATE: - error = ast_locate(dev, 0, *(u_int32_t *)data); - break; - - case MTIOCHLOCATE: - error = ast_locate(dev, 1, *(u_int32_t *)data); - break; - - default: - error = ata_device_ioctl(dev, cmd, data); - } - return error; -} - -static void -ast_strategy(struct bio *bp) -{ - device_t dev = bp->bio_dev->si_drv1; - struct ast_softc *stp = device_get_ivars(dev); - struct ata_request *request; - u_int32_t blkcount; - int8_t ccb[16]; - - /* if it's a null transfer, return immediatly. */ - if (bp->bio_bcount == 0) { - bp->bio_resid = 0; - biodone(bp); - return; - } - if (!(bp->bio_cmd == BIO_READ) && stp->flags & F_WRITEPROTECT) { - biofinish(bp, NULL, EPERM); - return; - } - - /* check for != blocksize requests */ - if (bp->bio_bcount % stp->blksize) { - device_printf(dev, "transfers must be multiple of %d\n", stp->blksize); - biofinish(bp, NULL, EIO); - return; - } - - /* warn about transfers bigger than the device suggests */ - if (bp->bio_bcount > stp->blksize * stp->cap.ctl) { - if ((stp->flags & F_CTL_WARN) == 0) { - device_printf(dev, "WARNING: CTL exceeded %ld>%d\n", - bp->bio_bcount, stp->blksize * stp->cap.ctl); - stp->flags |= F_CTL_WARN; - } - } - - bzero(ccb, sizeof(ccb)); - - if (bp->bio_cmd == BIO_READ) - ccb[0] = ATAPI_READ; - else - ccb[0] = ATAPI_WRITE; - - blkcount = bp->bio_bcount / stp->blksize; - - ccb[1] = 1; - ccb[2] = blkcount >> 16; - ccb[3] = blkcount >> 8; - ccb[4] = blkcount; - - if (!(request = ata_alloc_request())) { - biofinish(bp, NULL, ENOMEM); - return; - } - request->dev = dev; - request->driver = bp; - bcopy(ccb, request->u.atapi.ccb, 16); - request->data = bp->bio_data; - request->bytecount = blkcount * stp->blksize; - request->transfersize = min(request->bytecount, 65534); - request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 180 : 120; - request->retries = 2; - request->callback = ast_done; - switch (bp->bio_cmd) { - case BIO_READ: - request->flags |= (ATA_R_ATAPI | ATA_R_READ); - break; - case BIO_WRITE: - request->flags |= (ATA_R_ATAPI | ATA_R_WRITE); - break; - default: - device_printf(dev, "unknown BIO operation\n"); - ata_free_request(request); - biofinish(bp, NULL, EIO); - return; - } - devstat_start_transaction_bio(stp->stats, bp); - ata_queue_request(request); -} - -static void -ast_done(struct ata_request *request) -{ - struct ast_softc *stp = device_get_ivars(request->dev); - struct bio *bp = request->driver; - - /* finish up transfer */ - if ((bp->bio_error = request->result)) - bp->bio_flags |= BIO_ERROR; - if (bp->bio_cmd == BIO_WRITE) - stp->flags |= F_DATA_WRITTEN; - bp->bio_resid = bp->bio_bcount - request->donecount; - ast_total += (bp->bio_bcount - bp->bio_resid); - biofinish(bp, stp->stats, 0); - ata_free_request(request); -} - -static int -ast_sense(device_t dev) -{ - struct ast_softc *stp = device_get_ivars(dev); - int count; - - /* get drive capabilities, some bugridden drives needs this repeated */ - for (count = 0 ; count < 5 ; count++) { - if (!ast_mode_sense(dev, ATAPI_TAPE_CAP_PAGE, - &stp->cap, sizeof(stp->cap)) && - stp->cap.page_code == ATAPI_TAPE_CAP_PAGE) { - if (stp->cap.blk32k) - stp->blksize = 32768; - if (stp->cap.blk1024) - stp->blksize = 1024; - if (stp->cap.blk512) - stp->blksize = 512; - if (!stp->blksize) - continue; - stp->cap.max_speed = ntohs(stp->cap.max_speed); - stp->cap.max_defects = ntohs(stp->cap.max_defects); - stp->cap.ctl = ntohs(stp->cap.ctl); - stp->cap.speed = ntohs(stp->cap.speed); - stp->cap.buffer_size = ntohs(stp->cap.buffer_size); - return 0; - } - } - return 1; -} - -static int -ast_mode_sense(device_t dev, int page, void *pagebuf, int pagesize) -{ - int8_t ccb[16] = { ATAPI_MODE_SENSE, 0x08, page, pagesize>>8, pagesize, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, pagebuf, pagesize, ATA_R_READ, 10); - return error; -} - -static int -ast_mode_select(device_t dev, void *pagebuf, int pagesize) -{ - int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, pagesize>>8, pagesize, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, pagebuf, pagesize, 0, 10); -} - -static int -ast_write_filemark(device_t dev, u_int8_t function) -{ - struct ast_softc *stp = device_get_ivars(dev); - int8_t ccb[16] = { ATAPI_WEOF, 0x01, 0, 0, function, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - if (stp->flags & F_ONSTREAM) - ccb[4] = 0x00; /* only flush buffers supported */ - else { - if (function) { - if (stp->flags & F_FM_WRITTEN) - stp->flags &= ~F_DATA_WRITTEN; - else - stp->flags |= F_FM_WRITTEN; - } - } - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10); - if (error) - return error; - return ast_wait_dsc(dev, 10*60); -} - -static int -ast_read_position(device_t dev, int hard, struct ast_readposition *position) -{ - int8_t ccb[16] = { ATAPI_READ_POSITION, (hard ? 0x01 : 0), 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, (caddr_t)position, - sizeof(struct ast_readposition), ATA_R_READ, 10); - position->tape = ntohl(position->tape); - position->host = ntohl(position->host); - return error; -} - -static int -ast_space(device_t dev, u_int8_t function, int32_t count) -{ - int8_t ccb[16] = { ATAPI_SPACE, function, count>>16, count>>8, count, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 60*60); -} - -static int -ast_locate(device_t dev, int hard, u_int32_t pos) -{ - int8_t ccb[16] = { ATAPI_LOCATE, 0x01 | (hard ? 0x4 : 0), 0, - pos>>24, pos>>16, pos>>8, pos, - 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10); - if (error) - return error; - return ast_wait_dsc(dev, 60*60); -} - -static int -ast_prevent_allow(device_t dev, int lock) -{ - int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -ast_load_unload(device_t dev, u_int8_t function) -{ - struct ast_softc *stp = device_get_ivars(dev); - int8_t ccb[16] = { ATAPI_START_STOP, 0x01, 0, 0, function, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - if ((function & ATAPI_SS_EJECT) && !stp->cap.eject) - return 0; - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10); - if (error) - return error; - pause("astlu", 1 * hz); - if (function == ATAPI_SS_EJECT) - return 0; - return ast_wait_dsc(dev, 60*60); -} - -static int -ast_rewind(device_t dev) -{ - int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 10); - if (error) - return error; - return ast_wait_dsc(dev, 60*60); -} - -static int -ast_erase(device_t dev) -{ - int8_t ccb[16] = { ATAPI_ERASE, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 }; - int error; - - if ((error = ast_rewind(dev))) - return error; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 60*60); -} - -static int -ast_test_ready(device_t dev) -{ - int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - return ata_atapicmd(dev, ccb, NULL, 0, 0, 30); -} - -static int -ast_wait_dsc(device_t dev, int timeout) -{ - int error = 0; - int8_t ccb[16] = { ATAPI_POLL_DSC, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - timeout *= hz; - while (timeout > 0) { - error = ata_atapicmd(dev, ccb, NULL, 0, 0, 0); - if (error != EBUSY) - break; - pause("atpwt", hz / 2); - timeout -= (hz / 2); - } - return error; -} - -static void -ast_describe(device_t dev) -{ - struct ata_channel *ch = device_get_softc(device_get_parent(dev)); - struct ata_device *atadev = device_get_softc(dev); - struct ast_softc *stp = device_get_ivars(dev); - - if (bootverbose) { - device_printf(dev, "<%.40s/%.8s> tape drive at ata%d as %s\n", - atadev->param.model, atadev->param.revision, - device_get_unit(ch->dev), ata_unit2str(atadev)); - device_printf(dev, "%dKB/s, ", stp->cap.max_speed); - printf("transfer limit %d blk%s, ", - stp->cap.ctl, (stp->cap.ctl > 1) ? "s" : ""); - printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024); - printf("%s %s\n", ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - device_printf(dev, "Medium: "); - switch (stp->cap.medium_type) { - case 0x00: - printf("none"); break; - case 0x17: - printf("Travan 1 (400 Mbyte)"); break; - case 0xb6: - printf("Travan 4 (4 Gbyte)"); break; - case 0xda: - printf("OnStream ADR (15Gyte)"); break; - default: - printf("unknown (0x%x)", stp->cap.medium_type); - } - if (stp->cap.readonly) printf(", readonly"); - if (stp->cap.reverse) printf(", reverse"); - if (stp->cap.eformat) printf(", eformat"); - if (stp->cap.qfa) printf(", qfa"); - if (stp->cap.lock) printf(", lock"); - if (stp->cap.locked) printf(", locked"); - if (stp->cap.prevent) printf(", prevent"); - if (stp->cap.eject) printf(", eject"); - if (stp->cap.disconnect) printf(", disconnect"); - if (stp->cap.ecc) printf(", ecc"); - if (stp->cap.compress) printf(", compress"); - if (stp->cap.blk512) printf(", 512b"); - if (stp->cap.blk1024) printf(", 1024b"); - if (stp->cap.blk32k) printf(", 32kb"); - printf("\n"); - } - else { - device_printf(dev, "TAPE <%.40s/%.8s> at ata%d-%s %s %s\n", - atadev->param.model, atadev->param.revision, - device_get_unit(ch->dev), ata_unit2str(atadev), - ata_mode2str(atadev->mode), - ata_satarev2str(ATA_GETREV(device_get_parent(dev), atadev->unit))); - } -} - -static device_method_t ast_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, ast_probe), - DEVMETHOD(device_attach, ast_attach), - DEVMETHOD(device_detach, ast_detach), - DEVMETHOD(device_shutdown, ast_shutdown), - - /* ATA methods */ - DEVMETHOD(ata_reinit, ast_reinit), - - DEVMETHOD_END -}; - -static driver_t ast_driver = { - "ast", - ast_methods, - 0, -}; - -static devclass_t ast_devclass; - -DRIVER_MODULE(ast, ata, ast_driver, ast_devclass, NULL, NULL); -MODULE_VERSION(ast, 1); -MODULE_DEPEND(ast, ata, 1, 1, 1); diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h deleted file mode 100644 index d1448c9..0000000 --- a/sys/dev/ata/atapi-tape.h +++ /dev/null @@ -1,157 +0,0 @@ -/*- - * Copyright (c) 1998 - 2008 Søren Schmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* ATAPI tape drive Capabilities and Mechanical Status Page */ -struct ast_cappage { - /* mode page data header */ - u_int8_t data_length; /* total length of data */ - u_int8_t medium_type; /* medium type (if any) */ - u_int8_t reserved :4; - u_int8_t mode :3; /* buffering mode */ - u_int8_t write_protect :1; /* media is writeprotected */ - u_int8_t blk_desc_len; /* block Descriptor Length */ - - /* capabilities page */ - u_int8_t page_code :6; -#define ATAPI_TAPE_CAP_PAGE 0x2a - - u_int8_t reserved0_6 :1; - u_int8_t ps :1; /* parameters saveable */ - u_int8_t page_length; /* page Length == 0x12 */ - u_int8_t reserved2; - u_int8_t reserved3; - u_int8_t readonly :1; /* read Only Mode */ - u_int8_t reserved4_1234 :4; - u_int8_t reverse :1; /* supports reverse direction */ - u_int8_t reserved4_67 :2; - u_int8_t reserved5_012 :3; - u_int8_t eformat :1; /* supports ERASE formatting */ - u_int8_t reserved5_4 :1; - u_int8_t qfa :1; /* supports QFA formats */ - u_int8_t reserved5_67 :2; - u_int8_t lock :1; /* supports locking media */ - u_int8_t locked :1; /* the media is locked */ - u_int8_t prevent :1; /* defaults to prevent state */ - u_int8_t eject :1; /* supports eject */ - u_int8_t disconnect :1; /* can break request > ctl */ - u_int8_t reserved6_5 :1; - u_int8_t ecc :1; /* supports error correction */ - u_int8_t compress :1; /* supports data compression */ - u_int8_t reserved7_0 :1; - u_int8_t blk512 :1; /* supports 512b block size */ - u_int8_t blk1024 :1; /* supports 1024b block size */ - u_int8_t reserved7_3456 :4; - u_int8_t blk32k :1; /* supports 32kb block size */ - u_int16_t max_speed; /* supported speed in KBps */ - u_int16_t max_defects; /* max stored defect entries */ - u_int16_t ctl; /* continuous transfer limit */ - u_int16_t speed; /* current Speed, in KBps */ - u_int16_t buffer_size; /* buffer Size, in 512 bytes */ - u_int8_t reserved18; - u_int8_t reserved19; -}; - -/* ATAPI OnStream ADR data transfer mode page (ADR unique) */ -struct ast_transferpage { - /* mode page data header */ - u_int8_t data_length; /* total length of data */ - u_int8_t medium_type; /* medium type (if any) */ - u_int8_t dsp; /* device specific parameter */ - u_int8_t blk_desc_len; /* block Descriptor Length */ - - /* data transfer page */ - u_int8_t page_code :6; -#define ATAPI_TAPE_TRANSFER_PAGE 0x30 - - u_int8_t reserved0_6 :1; - u_int8_t ps :1; /* parameters saveable */ - u_int8_t page_length; /* page Length == 0x02 */ - u_int8_t reserved2; - u_int8_t read32k :1; /* 32k blk size (data only) */ - u_int8_t read32k5 :1; /* 32.5k blk size (data&AUX) */ - u_int8_t reserved3_23 :2; - u_int8_t write32k :1; /* 32k blk size (data only) */ - u_int8_t write32k5 :1; /* 32.5k blk size (data&AUX) */ - u_int8_t reserved3_6 :1; - u_int8_t streaming :1; /* streaming mode enable */ -}; - -/* ATAPI OnStream ADR vendor identification mode page (ADR unique) */ -struct ast_identifypage { - /* mode page data header */ - u_int8_t data_length; /* total length of data */ - u_int8_t medium_type; /* medium type (if any) */ - u_int8_t dsp; /* device specific parameter */ - u_int8_t blk_desc_len; /* block Descriptor Length */ - - /* data transfer page */ - u_int8_t page_code :6; -#define ATAPI_TAPE_IDENTIFY_PAGE 0x36 - - u_int8_t reserved0_6 :1; - u_int8_t ps :1; /* parameters saveable */ - u_int8_t page_length; /* page Length == 0x06 */ - u_int8_t ident[4]; /* host id string */ - u_int8_t reserved6; - u_int8_t reserved7; -}; - -/* ATAPI read position structure */ -struct ast_readposition { - u_int8_t reserved0_05 :6; - u_int8_t eop :1; /* end of partition */ - u_int8_t bop :1; /* beginning of partition */ - u_int8_t reserved1; - u_int8_t reserved2; - u_int8_t reserved3; - u_int32_t host; /* frame address in buffer */ - u_int32_t tape; /* frame address on tape */ - u_int8_t reserved12; - u_int8_t reserved13; - u_int8_t reserved14; - u_int8_t blks_in_buf; /* blocks in buffer */ - u_int8_t reserved16; - u_int8_t reserved17; - u_int8_t reserved18; - u_int8_t reserved19; -}; - -struct ast_softc { - int flags; /* device state flags */ -#define F_CTL_WARN 0x0001 /* warned about CTL wrong? */ -#define F_WRITEPROTECT 0x0002 /* media is writeprotected */ -#define F_DATA_WRITTEN 0x0004 /* data has been written */ -#define F_FM_WRITTEN 0x0008 /* filemark has been written */ -#define F_ONSTREAM 0x0100 /* OnStream ADR device */ - - int blksize; /* block size (512 | 1024) */ - struct atapi_params *param; /* drive parameters table */ - struct ast_cappage cap; /* capabilities page info */ - struct devstat *stats; /* devstat entry */ - struct cdev *dev1, *dev2; /* device place holders */ -}; diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c index e66224f..bfa15e4 100644 --- a/sys/dev/ata/chipsets/ata-acard.c +++ b/sys/dev/ata/chipsets/ata-acard.c @@ -51,25 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include -#ifndef ATA_CAM -struct ata_serialize { - struct mtx locked_mtx; - int locked_ch; - int restart_ch; -}; -#endif - /* local prototypes */ static int ata_acard_chipinit(device_t dev); static int ata_acard_ch_attach(device_t dev); static int ata_acard_status(device_t dev); static int ata_acard_850_setmode(device_t dev, int target, int mode); static int ata_acard_86X_setmode(device_t dev, int target, int mode); -#ifndef ATA_CAM -static int ata_acard_chipdeinit(device_t dev); -static int ata_serialize(device_t dev, int flags); -static void ata_serialize_init(struct ata_serialize *serial); -#endif /* misc defines */ #define ATP_OLD 1 @@ -97,9 +84,6 @@ ata_acard_probe(device_t dev) ata_set_desc(dev); ctlr->chipinit = ata_acard_chipinit; -#ifndef ATA_CAM - ctlr->chipdeinit = ata_acard_chipdeinit; -#endif return (BUS_PROBE_DEFAULT); } @@ -107,9 +91,6 @@ static int ata_acard_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); -#ifndef ATA_CAM - struct ata_serialize *serial; -#endif if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; @@ -118,40 +99,15 @@ ata_acard_chipinit(device_t dev) ctlr->ch_detach = ata_pci_ch_detach; if (ctlr->chip->cfg1 == ATP_OLD) { ctlr->setmode = ata_acard_850_setmode; -#ifndef ATA_CAM - ctlr->locking = ata_serialize; - serial = malloc(sizeof(struct ata_serialize), - M_ATAPCI, M_WAITOK | M_ZERO); - ata_serialize_init(serial); - ctlr->chipset_data = serial; -#else /* Work around the lack of channel serialization in ATA_CAM. */ ctlr->channels = 1; device_printf(dev, "second channel ignored\n"); -#endif } else ctlr->setmode = ata_acard_86X_setmode; return 0; } -#ifndef ATA_CAM -static int -ata_acard_chipdeinit(device_t dev) -{ - struct ata_pci_controller *ctlr = device_get_softc(dev); - struct ata_serialize *serial; - - if (ctlr->chip->cfg1 == ATP_OLD) { - serial = ctlr->chipset_data; - mtx_destroy(&serial->locked_mtx); - free(serial, M_ATAPCI); - ctlr->chipset_data = NULL; - } - return (0); -} -#endif - static int ata_acard_ch_attach(device_t dev) { @@ -169,12 +125,8 @@ ata_acard_ch_attach(device_t dev) static int ata_acard_status(device_t dev) { - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); - if (ctlr->chip->cfg1 == ATP_OLD && - ATA_LOCKING(dev, ATA_LF_WHICH) != ch->unit) - return 0; if (ch->dma.flags & ATA_DMA_ACTIVE) { int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; @@ -243,56 +195,4 @@ ata_acard_86X_setmode(device_t dev, int target, int mode) return (mode); } -#ifndef ATA_CAM -static void -ata_serialize_init(struct ata_serialize *serial) -{ - - mtx_init(&serial->locked_mtx, "ATA serialize lock", NULL, MTX_DEF); - serial->locked_ch = -1; - serial->restart_ch = -1; -} - -static int -ata_serialize(device_t dev, int flags) -{ - struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); - struct ata_channel *ch = device_get_softc(dev); - struct ata_serialize *serial; - int res; - - serial = ctlr->chipset_data; - - mtx_lock(&serial->locked_mtx); - switch (flags) { - case ATA_LF_LOCK: - if (serial->locked_ch == -1) - serial->locked_ch = ch->unit; - if (serial->locked_ch != ch->unit) - serial->restart_ch = ch->unit; - break; - - case ATA_LF_UNLOCK: - if (serial->locked_ch == ch->unit) { - serial->locked_ch = -1; - if (serial->restart_ch != -1) { - if ((ch = ctlr->interrupt[serial->restart_ch].argument)) { - serial->restart_ch = -1; - mtx_unlock(&serial->locked_mtx); - ata_start(dev); - return -1; - } - } - } - break; - - case ATA_LF_WHICH: - break; - } - res = serial->locked_ch; - mtx_unlock(&serial->locked_mtx); - return res; -} -#endif - ATA_DECLARE_DRIVER(ata_acard); diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c index f6ea280..7976147 100644 --- a/sys/dev/ata/chipsets/ata-acerlabs.c +++ b/sys/dev/ata/chipsets/ata-acerlabs.c @@ -213,10 +213,8 @@ ata_ali_ch_attach(device_t dev) if (ch->dma.max_iosize > 256 * 512) ch->dma.max_iosize = 256 * 512; } -#ifdef ATA_CAM if (ctlr->chip->cfg2 & ALI_NEW) ch->flags |= ATA_NO_ATAPI_DMA; -#endif return 0; } diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c index b2cd714..93c2f79 100644 --- a/sys/dev/ata/chipsets/ata-intel.c +++ b/sys/dev/ata/chipsets/ata-intel.c @@ -908,9 +908,6 @@ static void ata_intel_31244_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); -#ifndef ATA_CAM - struct ata_device *atadev = device_get_softc(request->dev); -#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); @@ -926,38 +923,12 @@ ata_intel_31244_tf_write(struct ata_request *request) else { ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); -#ifndef ATA_CAM - if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; - - if (atadev->param.atavalid & ATA_FLAG_54_58) { - heads = atadev->param.current_heads; - sectors = atadev->param.current_sectors; - } - 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, - (request->u.ata.lba / (sectors * heads))); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, - (request->u.ata.lba / (sectors * heads)) >> 8); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | - (((request->u.ata.lba% (sectors * heads)) / - sectors) & 0xf)); - } - else { -#endif 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 | ATA_DEV(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); -#ifndef ATA_CAM - } -#endif } } diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c index 2a7cfce..82a9920 100644 --- a/sys/dev/ata/chipsets/ata-ite.c +++ b/sys/dev/ata/chipsets/ata-ite.c @@ -119,9 +119,7 @@ ata_ite_ch_attach(device_t dev) error = ata_pci_ch_attach(dev); ch->flags |= ATA_CHECKS_CABLE; -#ifdef ATA_CAM ch->flags |= ATA_NO_ATAPI_DMA; -#endif return (error); } diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c index e5ee84b..b78dc70 100644 --- a/sys/dev/ata/chipsets/ata-serverworks.c +++ b/sys/dev/ata/chipsets/ata-serverworks.c @@ -288,9 +288,6 @@ static void ata_serverworks_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(request->parent); -#ifndef ATA_CAM - struct ata_device *atadev = device_get_softc(request->dev); -#endif if (request->flags & ATA_R_48BIT) { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); @@ -306,38 +303,12 @@ ata_serverworks_tf_write(struct ata_request *request) else { ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); -#ifndef ATA_CAM - if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; - - if (atadev->param.atavalid & ATA_FLAG_54_58) { - heads = atadev->param.current_heads; - sectors = atadev->param.current_sectors; - } - else { - heads = atadev->param.heads; - sectors = atadev->param.sectors; - } - ATA_IDX_OUTW(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); - ATA_IDX_OUTW(ch, ATA_CYL_LSB, - (request->u.ata.lba / (sectors * heads))); - ATA_IDX_OUTW(ch, ATA_CYL_MSB, - (request->u.ata.lba / (sectors * heads)) >> 8); - ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(request->unit) | - (((request->u.ata.lba% (sectors * heads)) / - sectors) & 0xf)); - } - else { -#endif ATA_IDX_OUTW(ch, ATA_SECTOR, request->u.ata.lba); ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) | ((request->u.ata.lba >> 24) & 0x0f)); -#ifndef ATA_CAM - } -#endif } } diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index 7f043ab..2d5c9fd 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -240,9 +240,7 @@ ata_cmd_ch_attach(device_t dev) if (ctlr->chip->cfg2 & SII_INTR) ch->hw.status = ata_cmd_status; -#ifdef ATA_CAM ch->flags |= ATA_NO_ATAPI_DMA; -#endif return 0; } -- cgit v1.1