From 0a62b1be511c831bf032027d5bd101cedf1f45c7 Mon Sep 17 00:00:00 2001 From: David Rhodus Date: Mon, 5 Jan 2004 17:40:00 +0000 Subject: [PATCH] * Merge in changes from FreeBSD with some modification by drhodus. date: 2003/12/02 07:57:20; author: ps; state: Exp; After extensive QA cycles at 3ware, bring the driver in-line with all the issues which they found and asked to be changed so 3ware can offcially support the driver. Summary of the most significant changes: - TWE_OVERRIDE is no longer supported - If twe_getparam failed, bogus data would be returned to the caller - Cache the device unit in the twe_drive structure to aid debugging - Add the 3ware driver version. - Proper return error codes for many functions. - Track the minimum queue length statistics - 4.x compat: use the cached unit number from the twe_drive structure instead of the the cached si_drv2. 3ware found that after many loads and unloads that si_drv2 became corrupted. This did not happen in -current. --- sys/dev/raid/twe/twe.c | 161 ++++++++++++++++++++------------- sys/dev/raid/twe/twe_compat.h | 7 +- sys/dev/raid/twe/twe_freebsd.c | 120 ++++++++++++++++-------- sys/dev/raid/twe/twe_tables.h | 5 +- sys/dev/raid/twe/tweio.h | 12 ++- sys/dev/raid/twe/twereg.h | 4 +- sys/dev/raid/twe/twevar.h | 6 +- 7 files changed, 205 insertions(+), 110 deletions(-) diff --git a/sys/dev/raid/twe/twe.c b/sys/dev/raid/twe/twe.c index ac5744d4bf..f7f20083c8 100644 --- a/sys/dev/raid/twe/twe.c +++ b/sys/dev/raid/twe/twe.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe.c,v 1.1.2.6 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe.c,v 1.4 2003/08/07 21:17:09 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe.c,v 1.5 2004/01/05 17:40:00 drhodus Exp $ */ /* @@ -61,6 +61,8 @@ static int twe_wait_request(struct twe_request *tr); static int twe_immediate_request(struct twe_request *tr); static void twe_completeio(struct twe_request *tr); static void twe_reset(struct twe_softc *sc); +static void twe_add_unit(struct twe_softc *sc, int unit); +static void twe_del_unit(struct twe_softc *sc, int unit); /* * Command I/O to controller. @@ -190,18 +192,17 @@ twe_setup(struct twe_softc *sc) return(0); } -/******************************************************************************** - * Locate disk devices and attach children to them. - */ -void -twe_init(struct twe_softc *sc) +static void +twe_add_unit(struct twe_softc *sc, int unit) { struct twe_drive *dr; - int i, table; + int table; u_int16_t dsize; - TWE_Param *drives, *param; + TWE_Param *drives = NULL, *param = NULL; TWE_Unit_Descriptor *ud; + if (unit < 0 || unit > TWE_MAX_UNITS) + return; /* * The controller is in a safe state, so try to find drives attached to it. @@ -211,52 +212,76 @@ twe_init(struct twe_softc *sc) twe_printf(sc, "can't detect attached units\n"); return; } - - /* - * For each detected unit, create a child device. - */ - for (i = 0, dr = &sc->twe_drive[0]; i < TWE_MAX_UNITS; i++, dr++) { - /* check that the drive is online */ - if (!(drives->data[i] & TWE_PARAM_UNITSTATUS_Online)) - continue; + dr = &sc->twe_drive[unit]; + /* check that the drive is online */ + if (!(drives->data[unit] & TWE_PARAM_UNITSTATUS_Online)) + goto out; - table = TWE_PARAM_UNITINFO + i; + table = TWE_PARAM_UNITINFO + unit; - if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) { - twe_printf(sc, "error fetching capacity for unit %d\n", i); - continue; - } - if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) { - twe_printf(sc, "error fetching state for unit %d\n", i); - continue; - } - if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) { - twe_printf(sc, "error fetching descriptor size for unit %d\n", i); - continue; - } - if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) { - twe_printf(sc, "error fetching descriptor for unit %d\n", i); - continue; - } - ud = (TWE_Unit_Descriptor *)param->data; - dr->td_type = ud->configuration; + if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) { + twe_printf(sc, "error fetching capacity for unit %d\n", unit); + goto out; + } + if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) { + twe_printf(sc, "error fetching state for unit %d\n", unit); + goto out; + } + if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) { + twe_printf(sc, "error fetching descriptor size for unit %d\n", unit); + goto out; + } + if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) { + twe_printf(sc, "error fetching descriptor for unit %d\n", unit); + goto out; + } + ud = (TWE_Unit_Descriptor *)param->data; + dr->td_type = ud->configuration; + + /* build synthetic geometry as per controller internal rules */ + if (dr->td_size > 0x200000) { + dr->td_heads = 255; + dr->td_sectors = 63; + } else { + dr->td_heads = 64; + dr->td_sectors = 32; + } + dr->td_cylinders = dr->td_size / (dr->td_heads * dr->td_sectors); + dr->td_unit = unit; + + twe_attach_drive(sc, dr); + +out: + if (param != NULL) free(param, M_DEVBUF); + if (drives != NULL) + free(drives, M_DEVBUF); +} - /* build synthetic geometry as per controller internal rules */ - if (dr->td_size > 0x200000) { - dr->td_heads = 255; - dr->td_sectors = 63; - } else { - dr->td_heads = 64; - dr->td_sectors = 32; - } - dr->td_cylinders = dr->td_size / (dr->td_heads * dr->td_sectors); - dr->td_unit = i; +static void +twe_del_unit(struct twe_softc *sc, int unit) +{ - twe_attach_drive(sc, dr); - } - free(drives, M_DEVBUF); + if (unit < 0 || unit > TWE_MAX_UNITS) + return; + + twe_detach_drive(sc, unit); +} + +/******************************************************************************** + * Locate disk devices and attach children to them. + */ +void +twe_init(struct twe_softc *sc) +{ + int i; + + /* + * Scan for drives + */ + for (i = 0; i < TWE_MAX_UNITS; i++) + twe_add_unit(sc, i); /* * Initialise connection with controller. @@ -448,6 +473,7 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) { struct twe_usercommand *tu = (struct twe_usercommand *)addr; struct twe_paramcommand *tp = (struct twe_paramcommand *)addr; + struct twe_drivecommand *td = (struct twe_drivecommand *)addr; union twe_statrequest *ts = (union twe_statrequest *)addr; TWE_Param *param; void *data; @@ -461,10 +487,8 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) /* handle a command from userspace */ case TWEIO_COMMAND: /* get a request */ - if (twe_get_request(sc, &tr)) { - error = EBUSY; - goto cmd_done; - } + while (twe_get_request(sc, &tr)) + tsleep(NULL, PPAUSE, "twioctl", hz); /* * Save the command's request ID, copy the user-supplied command in, @@ -474,14 +498,17 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) bcopy(&tu->tu_command, &tr->tr_command, sizeof(TWE_Command)); tr->tr_command.generic.request_id = srid; - /* if there's a data buffer, allocate and copy it in */ - tr->tr_length = tu->tu_size; + /* + * if there's a data buffer, allocate and copy it in. + * Must be in multipled of 512 bytes. + */ + tr->tr_length = (tu->tu_size + 511) & ~511; if (tr->tr_length > 0) { if ((tr->tr_data = malloc(tr->tr_length, M_DEVBUF, M_WAITOK)) == NULL) { error = ENOMEM; goto cmd_done; } - if ((error = copyin(tu->tu_data, tr->tr_data, tr->tr_length)) != 0) + if ((error = copyin(tu->tu_data, tr->tr_data, tu->tu_size)) != 0) goto cmd_done; tr->tr_flags |= TWE_CMD_DATAIN | TWE_CMD_DATAOUT; } @@ -495,7 +522,7 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) /* if there was a data buffer, copy it out */ if (tr->tr_length > 0) - error = copyout(tr->tr_data, tu->tu_data, tr->tr_length); + error = copyout(tr->tr_data, tu->tu_data, tu->tu_size); cmd_done: /* free resources */ @@ -527,15 +554,13 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) /* poll for an AEN */ case TWEIO_AEN_POLL: *arg = twe_dequeue_aen(sc); - if (*arg == -1) - error = ENOENT; break; /* wait for another AEN to show up */ case TWEIO_AEN_WAIT: s = splbio(); - while ((*arg = twe_dequeue_aen(sc)) == -1) { - error = tsleep(&sc->twe_aen_queue, PCATCH, "tweaen", 0); + while ((*arg = twe_dequeue_aen(sc)) == TWE_AEN_QUEUE_EMPTY) { + error = tsleep(&sc->twe_aen_queue, PRIBIO | PCATCH, "tweaen", 0); if (error == EINTR) break; } @@ -574,6 +599,14 @@ twe_ioctl(struct twe_softc *sc, int cmd, void *addr) twe_reset(sc); break; + case TWEIO_ADD_UNIT: + twe_add_unit(sc, td->td_unit); + break; + + case TWEIO_DEL_UNIT: + twe_del_unit(sc, td->td_unit); + break; + /* XXX implement ATA PASSTHROUGH */ /* nothing we understand */ @@ -867,7 +900,7 @@ twe_wait_request(struct twe_request *tr) twe_startio(tr->tr_sc); s = splbio(); while (tr->tr_status == TWE_CMD_BUSY) - tsleep(tr, 0, "twewait", 0); + tsleep(tr, PRIBIO, "twewait", 0); splx(s); return(0); @@ -932,7 +965,7 @@ twe_reset(struct twe_softc *sc) /* * Sleep for a short period to allow AENs to be signalled. */ - tsleep(NULL, 0, "twereset", hz); + tsleep(NULL, PRIBIO, "twereset", hz); /* * Disable interrupts from the controller, and mask any accidental entry @@ -1395,7 +1428,7 @@ twe_dequeue_aen(struct twe_softc *sc) debug_called(4); if (sc->twe_aen_tail == sc->twe_aen_head) { - result = -1; + result = TWE_AEN_QUEUE_EMPTY; } else { result = sc->twe_aen_queue[sc->twe_aen_tail]; sc->twe_aen_tail = ((sc->twe_aen_tail + 1) % TWE_Q_LENGTH); @@ -1447,7 +1480,7 @@ twe_wait_aen(struct twe_softc *sc, int aen, int timeout) sc->twe_wait_aen = aen; do { twe_fetch_aen(sc); - tsleep(&sc->twe_wait_aen, 0, "twewaen", hz); + tsleep(&sc->twe_wait_aen, PZERO, "twewaen", hz); if (sc->twe_wait_aen == -1) found = 1; } while ((time_second <= expiry) && !found); diff --git a/sys/dev/raid/twe/twe_compat.h b/sys/dev/raid/twe/twe_compat.h index 913fed6487..60cb059a31 100644 --- a/sys/dev/raid/twe/twe_compat.h +++ b/sys/dev/raid/twe/twe_compat.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe_compat.h,v 1.1.2.3 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe_compat.h,v 1.4 2003/08/07 21:17:09 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe_compat.h,v 1.5 2004/01/05 17:40:00 drhodus Exp $ */ /* * Portability and compatibility interfaces. @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -114,7 +115,9 @@ bus_dma_tag_t twe_buffer_dmat; /* data buffer DMA tag */ \ struct resource *twe_irq; /* interrupt */ \ void *twe_intr; /* interrupt handle */ \ - struct intr_config_hook twe_ich; /* delayed-startup hook */ + struct intr_config_hook twe_ich; /* delayed-startup hook */ \ + struct sysctl_ctx_list sysctl_ctx; \ + struct sysctl_oid *sysctl_tree; /* * FreeBSD-specific request elements diff --git a/sys/dev/raid/twe/twe_freebsd.c b/sys/dev/raid/twe/twe_freebsd.c index 50a2d9df38..7bd5db530a 100644 --- a/sys/dev/raid/twe/twe_freebsd.c +++ b/sys/dev/raid/twe/twe_freebsd.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.2.2.5 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.7 2003/11/15 21:05:42 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.8 2004/01/05 17:40:00 drhodus Exp $ */ /* @@ -137,7 +137,7 @@ static int twe_probe(device_t dev); static int twe_attach(device_t dev); static void twe_free(struct twe_softc *sc); static int twe_detach(device_t dev); -static int twe_shutdown(device_t dev); +static void twe_shutdown(device_t dev); static int twe_suspend(device_t dev); static int twe_resume(device_t dev); static void twe_pci_intr(void *arg); @@ -209,6 +209,18 @@ twe_attach(device_t dev) sc = device_get_softc(dev); sc->twe_dev = dev; + sysctl_ctx_init(&sc->sysctl_ctx); + sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, + device_get_nameunit(dev), CTLFLAG_RD, 0, ""); + if (sc->sysctl_tree == NULL) { + twe_printf(sc, "cannot add sysctl tree node\n"); + return (ENXIO); + } + SYSCTL_ADD_STRING(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), + OID_AUTO, "driver_version", CTLFLAG_RD, "$Revision$", 0, + "TWE driver version"); + /* * Make sure we are going to be able to talk to this board. */ @@ -355,6 +367,8 @@ twe_free(struct twe_softc *sc) /* destroy control device */ if (sc->twe_dev_t != (dev_t)NULL) destroy_dev(sc->twe_dev_t); + + sysctl_ctx_free(&sc->sysctl_ctx); } /******************************************************************************** @@ -376,8 +390,7 @@ twe_detach(device_t dev) /* * Shut the controller down. */ - if ((error = twe_shutdown(dev))) - goto out; + twe_shutdown(dev); twe_free(sc); @@ -393,26 +406,21 @@ twe_detach(device_t dev) * Note that we can assume that the bioq on the controller is empty, as we won't * allow shutdown if any device is open. */ -static int +static void twe_shutdown(device_t dev) { struct twe_softc *sc = device_get_softc(dev); - int i, s, error; + int i, s; debug_called(4); s = splbio(); - error = 0; /* * Delete all our child devices. */ for (i = 0; i < TWE_MAX_UNITS; i++) { - if (sc->twe_drive[i].td_disk != 0) { - if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[i].td_disk)) != 0) - goto out; - sc->twe_drive[i].td_disk = 0; - } + twe_detach_drive(sc, i); } /* @@ -420,9 +428,7 @@ twe_shutdown(device_t dev) */ twe_deinit(sc); - out: splx(s); - return(error); } /******************************************************************************** @@ -489,7 +495,7 @@ twe_intrhook(void *arg) /******************************************************************************** * Given a detected drive, attach it to the bio interface. * - * This is called from twe_init. + * This is called from twe_add_unit. */ void twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) @@ -508,7 +514,9 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) * XXX It would make sense to test the online/initialising bits, but they seem to be * always set... */ - sprintf(buf, "%s, %s", twe_describe_code(twe_table_unittype, dr->td_type), + sprintf(buf, "Unit %d, %s, %s", + dr->td_unit, + twe_describe_code(twe_table_unittype, dr->td_type), twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK)); device_set_desc_copy(dr->td_disk, buf); @@ -516,6 +524,22 @@ twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) twe_printf(sc, "bus_generic_attach returned %d\n", error); } +/******************************************************************************** + * Detach the specified unit if it exsists + * + * This is called from twe_del_unit. + */ +void +twe_detach_drive(struct twe_softc *sc, int unit) +{ + + if (sc->twe_drive[unit].td_disk != 0) { + if (device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk) != 0) + twe_printf(sc, "failed to delete unit %d\n", unit); + sc->twe_drive[unit].td_disk = 0; + } +} + /******************************************************************************** * Clear a PCI parity error. */ @@ -610,9 +634,10 @@ static struct cdevsw twed_cdevsw = { nommap, twed_strategy, twed_dump, - nopsize + nopsize, }; + /******************************************************************************** * Handle open from generic layer. * @@ -707,7 +732,7 @@ twed_dump(dev_t dev) struct twed_softc *twed_sc = (struct twed_softc *)dev->si_drv1; struct twe_softc *twe_sc = (struct twe_softc *)twed_sc->twed_controller; u_int count, blkno, secsize; - vm_offset_t addr = 0; + vm_paddr_t addr = 0; long blkcnt; int dumppages = MAXDUMPPGS; int error; @@ -728,7 +753,7 @@ twed_dump(dev_t dev) dumppages = count / blkcnt; for (i = 0; i < dumppages; ++i) { - vm_offset_t a = addr + (i * PAGE_SIZE); + vm_paddr_t a = addr + (i * PAGE_SIZE); if (is_physical_memory(a)) va = pmap_kenter_temporary(trunc_page(a), i); else @@ -903,12 +928,26 @@ twe_free_request(struct twe_request *tr) * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned * and we take care of that here as well. */ +static void +twe_fillin_sgl(TWE_SG_Entry *sgl, bus_dma_segment_t *segs, int nsegments, int max_sgl) +{ + int i; + + for (i = 0; i < nsegments; i++) { + sgl[i].address = segs[i].ds_addr; + sgl[i].length = segs[i].ds_len; + } + for (; i < max_sgl; i++) { /* XXX necessary? */ + sgl[i].address = 0; + sgl[i].length = 0; + } +} + static void twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) { struct twe_request *tr = (struct twe_request *)arg; TWE_Command *cmd = &tr->tr_command; - int i; debug_called(4); @@ -927,30 +966,35 @@ twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int err case TWE_OP_GET_PARAM: case TWE_OP_SET_PARAM: cmd->generic.sgl_offset = 2; - for (i = 0; i < nsegments; i++) { - cmd->param.sgl[i].address = segs[i].ds_addr; - cmd->param.sgl[i].length = segs[i].ds_len; - } - for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ - cmd->param.sgl[i].address = 0; - cmd->param.sgl[i].length = 0; - } + twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); break; case TWE_OP_READ: case TWE_OP_WRITE: cmd->generic.sgl_offset = 3; - for (i = 0; i < nsegments; i++) { - cmd->io.sgl[i].address = segs[i].ds_addr; - cmd->io.sgl[i].length = segs[i].ds_len; - } - for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ - cmd->io.sgl[i].address = 0; - cmd->io.sgl[i].length = 0; - } + twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); break; - default: - /* no s/g list, nothing to do */ + case TWE_OP_ATA_PASSTHROUGH: + cmd->generic.sgl_offset = 5; + twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH); break; + default: + /* + * Fall back to what the linux driver does. + * Do this because the API may send an opcode + * the driver knows nothing about and this will + * at least stop PCIABRT's from hosing us. + */ + switch (cmd->generic.sgl_offset) { + case 2: + twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); + break; + case 3: + twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); + break; + case 5: + twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH); + break; + } } } diff --git a/sys/dev/raid/twe/twe_tables.h b/sys/dev/raid/twe/twe_tables.h index ece089b53d..8e3d31f78e 100644 --- a/sys/dev/raid/twe/twe_tables.h +++ b/sys/dev/raid/twe/twe_tables.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twe_tables.h,v 1.1.2.2 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twe_tables.h,v 1.2 2003/06/17 04:28:32 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twe_tables.h,v 1.3 2004/01/05 17:40:00 drhodus Exp $ */ /* @@ -144,6 +144,9 @@ struct twe_code_lookup twe_table_aen[] = { {"c verify complete", 0x2b}, {"p overwrote bad sector during rebuild", 0x2c}, {"p encountered bad sector during rebuild", 0x2d}, + {"a replacement drive too small", 0x2e}, + {"c array not previously initialized", 0x2f}, + {"p drive not supported", 0x30}, {"a aen queue full", 0xff}, {NULL, 0}, {"x unknown AEN", 0} diff --git a/sys/dev/raid/twe/tweio.h b/sys/dev/raid/twe/tweio.h index afc4749e33..5f5d2cd162 100644 --- a/sys/dev/raid/twe/tweio.h +++ b/sys/dev/raid/twe/tweio.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/tweio.h,v 1.1.2.2 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/tweio.h,v 1.2 2003/06/17 04:28:32 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/tweio.h,v 1.3 2004/01/05 17:40:00 drhodus Exp $ */ @@ -91,3 +91,13 @@ struct twe_paramcommand { * Request a controller soft-reset */ #define TWEIO_RESET _IO ('T', 106) + +/* + * Request a drive addition or deletion + */ +struct twe_drivecommand { + int td_unit; +}; + +#define TWEIO_ADD_UNIT _IOW ('U', 107, int) +#define TWEIO_DEL_UNIT _IOW ('U', 108, int) diff --git a/sys/dev/raid/twe/twereg.h b/sys/dev/raid/twe/twereg.h index d14d3c2983..15b3dae32f 100644 --- a/sys/dev/raid/twe/twereg.h +++ b/sys/dev/raid/twe/twereg.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twereg.h,v 1.1.2.4 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twereg.h,v 1.3 2003/09/22 21:45:22 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twereg.h,v 1.4 2004/01/05 17:40:00 drhodus Exp $ */ /* @@ -120,6 +120,7 @@ #define TWE_OP_FLUSH 0x0e #define TWE_OP_ABORT 0x0f #define TWE_OP_CHECKSTATUS 0x10 +#define TWE_OP_ATA_PASSTHROUGH 0x11 #define TWE_OP_GET_PARAM 0x12 #define TWE_OP_SET_PARAM 0x13 #define TWE_OP_CREATEUNIT 0x14 @@ -128,7 +129,6 @@ #define TWE_OP_SECTOR_INFO 0x1a #define TWE_OP_AEN_LISTEN 0x1c #define TWE_OP_CMD_PACKET 0x1d -#define TWE_OP_ATA_PASSTHROUGH 0x1e #define TWE_OP_CMD_WITH_DATA 0x1f /* command status values */ diff --git a/sys/dev/raid/twe/twevar.h b/sys/dev/raid/twe/twevar.h index 8b012a2f2c..0842eff369 100644 --- a/sys/dev/raid/twe/twevar.h +++ b/sys/dev/raid/twe/twevar.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/twe/twevar.h,v 1.1.2.4 2002/03/07 09:57:02 msmith Exp $ - * $DragonFly: src/sys/dev/raid/twe/twevar.h,v 1.2 2003/06/17 04:28:32 dillon Exp $ + * $DragonFly: src/sys/dev/raid/twe/twevar.h,v 1.3 2004/01/05 17:40:00 drhodus Exp $ */ #ifdef TWE_DEBUG @@ -145,7 +145,9 @@ extern void twe_enable_interrupts(struct twe_softc *sc); /* enable controller in extern void twe_disable_interrupts(struct twe_softc *sc); /* disable controller interrupts */ extern void twe_attach_drive(struct twe_softc *sc, - struct twe_drive *dr); /* attach drive when found in twe_init */ + struct twe_drive *dr); /* attach drive when found in twe_add_unit */ +extern void twe_detach_drive(struct twe_softc *sc, + int unit); /* detach drive */ extern void twe_clear_pci_parity_error(struct twe_softc *sc); extern void twe_clear_pci_abort(struct twe_softc *sc); extern void twed_intr(twe_bio *bp); /* return bio from core */ -- 2.41.0