git: 062a7b918fac - main - twe: Remove driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 11 May 2023 04:28:11 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=062a7b918fac638e0cce0d8c087d7f2190c59b1e
commit 062a7b918fac638e0cce0d8c087d7f2190c59b1e
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2023-05-11 04:24:12 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-05-11 04:24:12 +0000
twe: Remove driver
Sponsored by: Netflix
---
sys/amd64/conf/GENERIC | 1 -
sys/conf/NOTES | 5 -
sys/conf/files | 2 -
sys/dev/twe/twe.c | 1973 ---------------------------------------------
sys/dev/twe/twe_compat.h | 127 ---
sys/dev/twe/twe_freebsd.c | 1170 ---------------------------
sys/dev/twe/twe_tables.h | 169 ----
sys/dev/twe/tweio.h | 106 ---
sys/dev/twe/twereg.h | 496 ------------
sys/dev/twe/twevar.h | 274 -------
sys/modules/Makefile | 1 -
sys/modules/twe/Makefile | 30 -
12 files changed, 4354 deletions(-)
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index f3497ef91f63..8f2e5e9fccb4 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -195,7 +195,6 @@ device mlx # Mylex DAC960 family
device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s
#XXX pointer/int warnings
#device pst # Promise Supertrak SX6000
-device twe # 3ware ATA RAID
# NVM Express (NVMe) support
device nvme # base NVMe driver
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index a6c3c42fc00e..8725d11a5434 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1646,11 +1646,6 @@ device mfip # LSI MegaRAID SAS passthrough, requires CAM
options MFI_DEBUG
device mrsas # LSI/Avago MegaRAID SAS/SATA, 6Gb/s and 12Gb/s
-#
-# 3ware ATA RAID
-#
-device twe # 3ware ATA RAID
-
#
# Serial ATA host controllers:
#
diff --git a/sys/conf/files b/sys/conf/files
index 8c3d80c48b01..c0728504da5a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3171,8 +3171,6 @@ dev/syscons/warp/warp_saver.c optional warp_saver
dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6
dev/tdfx/tdfx_pci.c optional tdfx pci
dev/ti/if_ti.c optional ti pci
-dev/twe/twe.c optional twe
-dev/twe/twe_freebsd.c optional twe
dev/tws/tws.c optional tws
dev/tws/tws_cam.c optional tws
dev/tws/tws_hdm.c optional tws
diff --git a/sys/dev/twe/twe.c b/sys/dev/twe/twe.c
deleted file mode 100644
index 6d05ac7c2b95..000000000000
--- a/sys/dev/twe/twe.c
+++ /dev/null
@@ -1,1973 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2003 Paul Saab
- * Copyright (c) 2003 Vinod Kashyap
- * Copyright (c) 2000 BSDi
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
- */
-
-/*
- * Driver for the 3ware Escalade family of IDE RAID controllers.
- */
-
-#include <dev/twe/twe_compat.h>
-#include <dev/twe/twereg.h>
-#include <dev/twe/tweio.h>
-#include <dev/twe/twevar.h>
-#define TWE_DEFINE_TABLES
-#include <dev/twe/twe_tables.h>
-
-/*
- * Command submission.
- */
-static int twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result);
-static int twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result);
-static int twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result);
-static void *twe_get_param(struct twe_softc *sc, int table_id, int parameter_id, size_t size,
- void (* func)(struct twe_request *tr));
-#ifdef TWE_SHUTDOWN_NOTIFICATION
-static int twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value);
-#endif
-#if 0
-static int twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value);
-static int twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value);
-#endif
-static int twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size,
- void *data);
-static int twe_init_connection(struct twe_softc *sc, int mode);
-static int twe_wait_request(struct twe_request *tr);
-static int twe_immediate_request(struct twe_request *tr, int usetmp);
-static void twe_completeio(struct twe_request *tr);
-static void twe_reset(struct twe_softc *sc);
-static int twe_add_unit(struct twe_softc *sc, int unit);
-static int twe_del_unit(struct twe_softc *sc, int unit);
-
-/*
- * Command I/O to controller.
- */
-static void twe_done(struct twe_softc *sc, int startio);
-static void twe_complete(struct twe_softc *sc);
-static int twe_wait_status(struct twe_softc *sc, u_int32_t status, int timeout);
-static int twe_drain_response_queue(struct twe_softc *sc);
-static int twe_check_bits(struct twe_softc *sc, u_int32_t status_reg);
-static int twe_soft_reset(struct twe_softc *sc);
-
-/*
- * Interrupt handling.
- */
-static void twe_host_intr(struct twe_softc *sc);
-static void twe_attention_intr(struct twe_softc *sc);
-static void twe_command_intr(struct twe_softc *sc);
-
-/*
- * Asynchronous event handling.
- */
-static int twe_fetch_aen(struct twe_softc *sc);
-static void twe_handle_aen(struct twe_request *tr);
-static void twe_enqueue_aen(struct twe_softc *sc, u_int16_t aen);
-static u_int16_t twe_dequeue_aen(struct twe_softc *sc);
-static int twe_drain_aen_queue(struct twe_softc *sc);
-static int twe_find_aen(struct twe_softc *sc, u_int16_t aen);
-
-/*
- * Command buffer management.
- */
-static int twe_get_request(struct twe_softc *sc, struct twe_request **tr);
-static void twe_release_request(struct twe_request *tr);
-
-/*
- * Debugging.
- */
-static char *twe_format_aen(struct twe_softc *sc, u_int16_t aen);
-static int twe_report_request(struct twe_request *tr);
-static void twe_panic(struct twe_softc *sc, char *reason);
-
-/********************************************************************************
- ********************************************************************************
- Public Interfaces
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Initialise the controller, set up driver data structures.
- */
-int
-twe_setup(struct twe_softc *sc)
-{
- struct twe_request *tr;
- TWE_Command *cmd;
- u_int32_t status_reg;
- int i;
-
- debug_called(4);
-
- gone_in(14, "Please migrate to newer hardware");
-
- /*
- * Initialise request queues.
- */
- twe_initq_free(sc);
- twe_initq_bio(sc);
- twe_initq_ready(sc);
- twe_initq_busy(sc);
- twe_initq_complete(sc);
- sc->twe_wait_aen = -1;
-
- /*
- * Allocate request structures up front.
- */
- for (i = 0; i < TWE_Q_LENGTH; i++) {
- if ((tr = twe_allocate_request(sc, i)) == NULL)
- return(ENOMEM);
- /*
- * Set global defaults that won't change.
- */
- cmd = TWE_FIND_COMMAND(tr);
- cmd->generic.host_id = sc->twe_host_id; /* controller-assigned host ID */
- cmd->generic.request_id = i; /* our index number */
- sc->twe_lookup[i] = tr;
-
- /*
- * Put command onto the freelist.
- */
- TWE_IO_LOCK(sc);
- twe_release_request(tr);
- TWE_IO_UNLOCK(sc);
- }
- TWE_IO_LOCK(sc);
-
- /*
- * Check status register for errors, clear them.
- */
- status_reg = TWE_STATUS(sc);
- twe_check_bits(sc, status_reg);
-
- /*
- * Wait for the controller to come ready.
- */
- if (twe_wait_status(sc, TWE_STATUS_MICROCONTROLLER_READY, 60)) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "microcontroller not ready\n");
- return(ENXIO);
- }
-
- /*
- * Disable interrupts from the card.
- */
- twe_disable_interrupts(sc);
-
- /*
- * Soft reset the controller, look for the AEN acknowledging the reset,
- * check for errors, drain the response queue.
- */
- for (i = 0; i < TWE_MAX_RESET_TRIES; i++) {
- if (i > 0)
- twe_printf(sc, "reset %d failed, trying again\n", i);
-
- if (!twe_soft_reset(sc))
- break; /* reset process complete */
- }
- TWE_IO_UNLOCK(sc);
- /* did we give up? */
- if (i >= TWE_MAX_RESET_TRIES) {
- twe_printf(sc, "can't initialise controller, giving up\n");
- return(ENXIO);
- }
-
- return(0);
-}
-
-static int
-twe_add_unit(struct twe_softc *sc, int unit)
-{
- struct twe_drive *dr;
- int table, error = 0;
- u_int16_t dsize;
- TWE_Param *drives = NULL, *param = NULL;
- TWE_Array_Descriptor *ud;
-
- TWE_CONFIG_ASSERT_LOCKED(sc);
- if (unit < 0 || unit > TWE_MAX_UNITS)
- return (EINVAL);
-
- /*
- * The controller is in a safe state, so try to find drives attached to it.
- */
- TWE_IO_LOCK(sc);
- if ((drives = twe_get_param(sc, TWE_PARAM_UNITSUMMARY, TWE_PARAM_UNITSUMMARY_Status,
- TWE_MAX_UNITS, NULL)) == NULL) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "can't detect attached units\n");
- return (EIO);
- }
-
- dr = &sc->twe_drive[unit];
- /* check that the drive is online */
- if (!(drives->data[unit] & TWE_PARAM_UNITSTATUS_Online)) {
- TWE_IO_UNLOCK(sc);
- error = ENXIO;
- goto out;
- }
-
- table = TWE_PARAM_UNITINFO + unit;
-
- if (twe_get_param_4(sc, table, TWE_PARAM_UNITINFO_Capacity, &dr->td_size)) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "error fetching capacity for unit %d\n", unit);
- error = EIO;
- goto out;
- }
- if (twe_get_param_1(sc, table, TWE_PARAM_UNITINFO_Status, &dr->td_state)) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "error fetching state for unit %d\n", unit);
- error = EIO;
- goto out;
- }
- if (twe_get_param_2(sc, table, TWE_PARAM_UNITINFO_DescriptorSize, &dsize)) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "error fetching descriptor size for unit %d\n", unit);
- error = EIO;
- goto out;
- }
- if ((param = twe_get_param(sc, table, TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL)) == NULL) {
- TWE_IO_UNLOCK(sc);
- twe_printf(sc, "error fetching descriptor for unit %d\n", unit);
- error = EIO;
- goto out;
- }
- ud = (TWE_Array_Descriptor *)param->data;
- dr->td_type = ud->configuration;
- dr->td_stripe = ud->stripe_size;
-
- /* 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_twe_unit = unit;
- TWE_IO_UNLOCK(sc);
-
- error = twe_attach_drive(sc, dr);
-
-out:
- if (param != NULL)
- free(param, M_DEVBUF);
- if (drives != NULL)
- free(drives, M_DEVBUF);
- return (error);
-}
-
-static int
-twe_del_unit(struct twe_softc *sc, int unit)
-{
- int error;
-
- TWE_CONFIG_ASSERT_LOCKED(sc);
- if (unit < 0 || unit >= TWE_MAX_UNITS)
- return (ENXIO);
-
- if (sc->twe_drive[unit].td_disk == NULL)
- return (ENXIO);
-
- error = twe_detach_drive(sc, unit);
- return (error);
-}
-
-/********************************************************************************
- * Locate disk devices and attach children to them.
- */
-void
-twe_init(struct twe_softc *sc)
-{
- int i;
-
- /*
- * Scan for drives
- */
- TWE_CONFIG_LOCK(sc);
- for (i = 0; i < TWE_MAX_UNITS; i++)
- twe_add_unit(sc, i);
- TWE_CONFIG_UNLOCK(sc);
-
- /*
- * Initialise connection with controller.
- */
- TWE_IO_LOCK(sc);
- twe_init_connection(sc, TWE_INIT_MESSAGE_CREDITS);
-
-#ifdef TWE_SHUTDOWN_NOTIFICATION
- /*
- * Tell the controller we support shutdown notification.
- */
- twe_set_param_1(sc, TWE_PARAM_FEATURES, TWE_PARAM_FEATURES_DriverShutdown, 1);
-#endif
-
- /*
- * Mark controller up and ready to run.
- */
- sc->twe_state &= ~TWE_STATE_SHUTDOWN;
-
- /*
- * Finally enable interrupts.
- */
- twe_enable_interrupts(sc);
- TWE_IO_UNLOCK(sc);
-}
-
-/********************************************************************************
- * Stop the controller
- */
-void
-twe_deinit(struct twe_softc *sc)
-{
- /*
- * Mark the controller as shutting down, and disable any further interrupts.
- */
- TWE_IO_ASSERT_LOCKED(sc);
- sc->twe_state |= TWE_STATE_SHUTDOWN;
- twe_disable_interrupts(sc);
-
-#ifdef TWE_SHUTDOWN_NOTIFICATION
- /*
- * Disconnect from the controller
- */
- twe_init_connection(sc, TWE_SHUTDOWN_MESSAGE_CREDITS);
-#endif
-}
-
-/*******************************************************************************
- * Take an interrupt, or be poked by other code to look for interrupt-worthy
- * status.
- */
-void
-twe_intr(struct twe_softc *sc)
-{
- u_int32_t status_reg;
-
- debug_called(4);
-
- /*
- * Collect current interrupt status.
- */
- status_reg = TWE_STATUS(sc);
- twe_check_bits(sc, status_reg);
-
- /*
- * Dispatch based on interrupt status
- */
- if (status_reg & TWE_STATUS_HOST_INTERRUPT)
- twe_host_intr(sc);
- if (status_reg & TWE_STATUS_ATTENTION_INTERRUPT)
- twe_attention_intr(sc);
- if (status_reg & TWE_STATUS_COMMAND_INTERRUPT)
- twe_command_intr(sc);
- if (status_reg & TWE_STATUS_RESPONSE_INTERRUPT)
- twe_done(sc, 1);
-};
-
-/********************************************************************************
- * Pull as much work off the softc's work queue as possible and give it to the
- * controller.
- */
-void
-twe_startio(struct twe_softc *sc)
-{
- struct twe_request *tr;
- TWE_Command *cmd;
- struct bio *bp;
- int error;
-
- debug_called(4);
-
- TWE_IO_ASSERT_LOCKED(sc);
- if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN))
- return;
-
- /* spin until something prevents us from doing any work */
- for (;;) {
- /* try to get a command that's already ready to go */
- tr = twe_dequeue_ready(sc);
-
- /* build a command from an outstanding bio */
- if (tr == NULL) {
-
- /* get a command to handle the bio with */
- if (twe_get_request(sc, &tr))
- break;
-
- /* see if there's work to be done */
- if ((bp = twe_dequeue_bio(sc)) == NULL) {
- twe_release_request(tr);
- break;
- }
-
- /* connect the bio to the command */
- tr->tr_complete = twe_completeio;
- tr->tr_private = bp;
- tr->tr_data = bp->bio_data;
- tr->tr_length = bp->bio_bcount;
- cmd = TWE_FIND_COMMAND(tr);
- if (bp->bio_cmd == BIO_READ) {
- tr->tr_flags |= TWE_CMD_DATAIN;
- cmd->io.opcode = TWE_OP_READ;
- } else if (bp->bio_cmd == BIO_WRITE) {
- tr->tr_flags |= TWE_CMD_DATAOUT;
- cmd->io.opcode = TWE_OP_WRITE;
- } else {
- twe_release_request(tr);
- biofinish(bp, NULL, EOPNOTSUPP);
- break;
- }
-
- /* build a suitable I/O command (assumes 512-byte rounded transfers) */
- cmd->io.size = 3;
- cmd->io.unit = *(int *)(bp->bio_driver1);
- cmd->io.block_count = (tr->tr_length + TWE_BLOCK_SIZE - 1) / TWE_BLOCK_SIZE;
- cmd->io.lba = bp->bio_pblkno;
- }
-
- /* did we find something to do? */
- if (tr == NULL)
- break;
-
- /* try to map and submit the command to controller */
- error = twe_map_request(tr);
-
- if (error != 0) {
- if (error == EBUSY)
- break;
- tr->tr_status = TWE_CMD_ERROR;
- if (tr->tr_private != NULL) {
- bp = (struct bio *)(tr->tr_private);
- bp->bio_error = error;
- bp->bio_flags |= BIO_ERROR;
- tr->tr_private = NULL;
- twed_intr(bp);
- twe_release_request(tr);
- } else if (tr->tr_flags & TWE_CMD_SLEEPER)
- wakeup_one(tr); /* wakeup the sleeping owner */
- }
- }
-}
-
-/********************************************************************************
- * Write blocks from memory to disk, for system crash dumps.
- */
-int
-twe_dump_blocks(struct twe_softc *sc, int unit, u_int32_t lba, void *data, int nblks)
-{
- struct twe_request *tr;
- TWE_Command *cmd;
- int error;
-
- if (twe_get_request(sc, &tr))
- return(ENOMEM);
-
- tr->tr_data = data;
- tr->tr_status = TWE_CMD_SETUP;
- tr->tr_length = nblks * TWE_BLOCK_SIZE;
- tr->tr_flags = TWE_CMD_DATAOUT;
-
- cmd = TWE_FIND_COMMAND(tr);
- cmd->io.opcode = TWE_OP_WRITE;
- cmd->io.size = 3;
- cmd->io.unit = unit;
- cmd->io.block_count = nblks;
- cmd->io.lba = lba;
-
- error = twe_immediate_request(tr, 0);
- if (error == 0)
- if (twe_report_request(tr))
- error = EIO;
- twe_release_request(tr);
- return(error);
-}
-
-/********************************************************************************
- * Handle controller-specific control operations.
- */
-int
-twe_ioctl(struct twe_softc *sc, u_long ioctlcmd, 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;
- TWE_Command *cmd;
- void *data;
- u_int16_t *aen_code = (u_int16_t *)addr;
- struct twe_request *tr;
- u_int8_t srid;
- int error;
- size_t tr_length;
-
- error = 0;
- switch(ioctlcmd) {
- /* handle a command from userspace */
- case TWEIO_COMMAND:
- /*
- * if there's a data buffer, allocate and copy it in.
- * Must be in multiplied of 512 bytes.
- */
- tr_length = roundup2(tu->tu_size, 512);
- if (tr_length > 0) {
- data = malloc(tr_length, M_DEVBUF, M_WAITOK);
- error = copyin(tu->tu_data, data, tu->tu_size);
- if (error) {
- free(data, M_DEVBUF);
- break;
- }
- } else
- data = NULL;
-
- /* get a request */
- TWE_IO_LOCK(sc);
- while (twe_get_request(sc, &tr))
- mtx_sleep(sc, &sc->twe_io_lock, PPAUSE, "twioctl", hz);
-
- /*
- * Save the command's request ID, copy the user-supplied command in,
- * restore the request ID.
- */
- cmd = TWE_FIND_COMMAND(tr);
- srid = cmd->generic.request_id;
- bcopy(&tu->tu_command, cmd, sizeof(TWE_Command));
- cmd->generic.request_id = srid;
-
- tr->tr_length = tr_length;
- tr->tr_data = data;
- if (tr->tr_length > 0) {
- tr->tr_flags |= TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
- }
-
- /* run the command */
- error = twe_wait_request(tr);
- TWE_IO_UNLOCK(sc);
- if (error)
- goto cmd_done;
-
- /* copy the command out again */
- bcopy(cmd, &tu->tu_command, sizeof(TWE_Command));
-
- /* if there was a data buffer, copy it out */
- if (tr->tr_length > 0)
- error = copyout(tr->tr_data, tu->tu_data, tu->tu_size);
-
- cmd_done:
- /* free resources */
- if (tr->tr_data != NULL)
- free(tr->tr_data, M_DEVBUF);
- TWE_IO_LOCK(sc);
- twe_release_request(tr);
- TWE_IO_UNLOCK(sc);
-
- break;
-
- /* fetch statistics counter */
- case TWEIO_STATS:
- switch (ts->ts_item) {
-#ifdef TWE_PERFORMANCE_MONITOR
- case TWEQ_FREE:
- case TWEQ_BIO:
- case TWEQ_READY:
- case TWEQ_BUSY:
- case TWEQ_COMPLETE:
- TWE_IO_LOCK(sc);
- bcopy(&sc->twe_qstat[ts->ts_item], &ts->ts_qstat, sizeof(struct twe_qstat));
- TWE_IO_UNLOCK(sc);
- break;
-#endif
- default:
- error = ENOENT;
- break;
- }
- break;
-
- /* poll for an AEN */
- case TWEIO_AEN_POLL:
- TWE_IO_LOCK(sc);
- *aen_code = twe_dequeue_aen(sc);
- TWE_IO_UNLOCK(sc);
- break;
-
- /* wait for another AEN to show up */
- case TWEIO_AEN_WAIT:
- TWE_IO_LOCK(sc);
- while ((*aen_code = twe_dequeue_aen(sc)) == TWE_AEN_QUEUE_EMPTY) {
- error = mtx_sleep(&sc->twe_aen_queue, &sc->twe_io_lock, PRIBIO | PCATCH,
- "tweaen", 0);
- if (error == EINTR)
- break;
- }
- TWE_IO_UNLOCK(sc);
- break;
-
- case TWEIO_GET_PARAM:
- TWE_IO_LOCK(sc);
- param = twe_get_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, NULL);
- TWE_IO_UNLOCK(sc);
- if (param == NULL) {
- twe_printf(sc, "TWEIO_GET_PARAM failed for 0x%x/0x%x/%d\n",
- tp->tp_table_id, tp->tp_param_id, tp->tp_size);
- error = EINVAL;
- } else {
- if (param->parameter_size_bytes > tp->tp_size) {
- twe_printf(sc, "TWEIO_GET_PARAM parameter too large (%d > %d)\n",
- param->parameter_size_bytes, tp->tp_size);
- error = EFAULT;
- } else {
- error = copyout(param->data, tp->tp_data, param->parameter_size_bytes);
- }
- free(param, M_DEVBUF);
- }
- break;
-
- case TWEIO_SET_PARAM:
- data = malloc(tp->tp_size, M_DEVBUF, M_WAITOK);
- error = copyin(tp->tp_data, data, tp->tp_size);
- if (error == 0) {
- TWE_IO_LOCK(sc);
- error = twe_set_param(sc, tp->tp_table_id, tp->tp_param_id, tp->tp_size, data);
- TWE_IO_UNLOCK(sc);
- }
- free(data, M_DEVBUF);
- break;
-
- case TWEIO_RESET:
- TWE_IO_LOCK(sc);
- twe_reset(sc);
- TWE_IO_UNLOCK(sc);
- break;
-
- case TWEIO_ADD_UNIT:
- TWE_CONFIG_LOCK(sc);
- error = twe_add_unit(sc, td->td_unit);
- TWE_CONFIG_UNLOCK(sc);
- break;
-
- case TWEIO_DEL_UNIT:
- TWE_CONFIG_LOCK(sc);
- error = twe_del_unit(sc, td->td_unit);
- TWE_CONFIG_UNLOCK(sc);
- break;
-
- /* XXX implement ATA PASSTHROUGH */
-
- /* nothing we understand */
- default:
- error = ENOTTY;
- }
-
- return(error);
-}
-
-/********************************************************************************
- * Enable the useful interrupts from the controller.
- */
-void
-twe_enable_interrupts(struct twe_softc *sc)
-{
- sc->twe_state |= TWE_STATE_INTEN;
- TWE_CONTROL(sc,
- TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT |
- TWE_CONTROL_UNMASK_RESPONSE_INTERRUPT |
- TWE_CONTROL_ENABLE_INTERRUPTS);
-}
-
-/********************************************************************************
- * Disable interrupts from the controller.
- */
-void
-twe_disable_interrupts(struct twe_softc *sc)
-{
- TWE_CONTROL(sc, TWE_CONTROL_DISABLE_INTERRUPTS);
- sc->twe_state &= ~TWE_STATE_INTEN;
-}
-
-/********************************************************************************
- ********************************************************************************
- Command Submission
- ********************************************************************************
- ********************************************************************************/
-
-/********************************************************************************
- * Read integer parameter table entries.
- */
-static int
-twe_get_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t *result)
-{
- TWE_Param *param;
-
- if ((param = twe_get_param(sc, table_id, param_id, 1, NULL)) == NULL)
- return(ENOENT);
- *result = *(u_int8_t *)param->data;
- free(param, M_DEVBUF);
- return(0);
-}
-
-static int
-twe_get_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t *result)
-{
- TWE_Param *param;
-
- if ((param = twe_get_param(sc, table_id, param_id, 2, NULL)) == NULL)
- return(ENOENT);
- *result = *(u_int16_t *)param->data;
- free(param, M_DEVBUF);
- return(0);
-}
-
-static int
-twe_get_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t *result)
-{
- TWE_Param *param;
-
- if ((param = twe_get_param(sc, table_id, param_id, 4, NULL)) == NULL)
- return(ENOENT);
- *result = *(u_int32_t *)param->data;
- free(param, M_DEVBUF);
- return(0);
-}
-
-/********************************************************************************
- * Perform a TWE_OP_GET_PARAM command. If a callback function is provided, it
- * will be called with the command when it's completed. If no callback is
- * provided, we will wait for the command to complete and then return just the data.
- * The caller is responsible for freeing the data when done with it.
- */
-static void *
-twe_get_param(struct twe_softc *sc, int table_id, int param_id, size_t param_size,
- void (* func)(struct twe_request *tr))
-{
- struct twe_request *tr;
- TWE_Command *cmd;
- TWE_Param *param;
- int error;
-
- debug_called(4);
-
- TWE_IO_ASSERT_LOCKED(sc);
- tr = NULL;
- param = NULL;
-
- /* get a command */
- if (twe_get_request(sc, &tr))
- goto err;
-
- /* get a buffer */
- if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
- goto err;
- tr->tr_data = param;
- tr->tr_length = TWE_SECTOR_SIZE;
- tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
-
- /* build the command for the controller */
- cmd = TWE_FIND_COMMAND(tr);
- cmd->param.opcode = TWE_OP_GET_PARAM;
- cmd->param.size = 2;
- cmd->param.unit = 0;
- cmd->param.param_count = 1;
-
- /* fill in the outbound parameter data */
- param->table_id = table_id;
- param->parameter_id = param_id;
- param->parameter_size_bytes = param_size;
-
- /* submit the command and either wait or let the callback handle it */
- if (func == NULL) {
- /* XXX could use twe_wait_request here if interrupts were enabled? */
- error = twe_immediate_request(tr, 1 /* usetmp */);
- if (error == 0) {
- if (twe_report_request(tr))
- goto err;
- } else {
- goto err;
- }
- twe_release_request(tr);
- return(param);
- } else {
- tr->tr_complete = func;
- error = twe_map_request(tr);
- if ((error == 0) || (error == EBUSY))
- return(func);
- }
-
- /* something failed */
-err:
- debug(1, "failed");
- if (tr != NULL)
- twe_release_request(tr);
- if (param != NULL)
- free(param, M_DEVBUF);
- return(NULL);
-}
-
-/********************************************************************************
- * Set integer parameter table entries.
- */
-#ifdef TWE_SHUTDOWN_NOTIFICATION
-static int
-twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value)
-{
- return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
-}
-#endif
-
-#if 0
-static int
-twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value)
-{
- return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
-}
-
-static int
-twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value)
-{
- return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
-}
-#endif
-
-/********************************************************************************
- * Perform a TWE_OP_SET_PARAM command, returns nonzero on error.
- */
-static int
-twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, void *data)
-{
- struct twe_request *tr;
- TWE_Command *cmd;
- TWE_Param *param;
- int error;
-
- debug_called(4);
-
- TWE_IO_ASSERT_LOCKED(sc);
- tr = NULL;
- param = NULL;
- error = ENOMEM;
-
- /* get a command */
- if (twe_get_request(sc, &tr))
- goto out;
-
- /* get a buffer */
- if ((param = (TWE_Param *)malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
- goto out;
- tr->tr_data = param;
- tr->tr_length = TWE_SECTOR_SIZE;
- tr->tr_flags = TWE_CMD_DATAIN | TWE_CMD_DATAOUT;
-
- /* build the command for the controller */
- cmd = TWE_FIND_COMMAND(tr);
- cmd->param.opcode = TWE_OP_SET_PARAM;
- cmd->param.size = 2;
- cmd->param.unit = 0;
- cmd->param.param_count = 1;
-
- /* fill in the outbound parameter data */
- param->table_id = table_id;
- param->parameter_id = param_id;
- param->parameter_size_bytes = param_size;
- bcopy(data, param->data, param_size);
-
- /* XXX could use twe_wait_request here if interrupts were enabled? */
- error = twe_immediate_request(tr, 1 /* usetmp */);
- if (error == 0) {
- if (twe_report_request(tr))
- error = EIO;
- }
-
-out:
- if (tr != NULL)
- twe_release_request(tr);
- if (param != NULL)
*** 3487 LINES SKIPPED ***