diff options
| author | Scott Long <scottl@FreeBSD.org> | 2003-02-05 23:24:25 +0000 |
|---|---|---|
| committer | Scott Long <scottl@FreeBSD.org> | 2003-02-05 23:24:25 +0000 |
| commit | 70545d1a1fbbf596c74a70db656e514835c7ae63 (patch) | |
| tree | f90e00f482bd8cdf7498b630a6cb4ee9915cc8d6 /sys | |
| parent | dba8967550353d363cebc915af52fe1301b4d092 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/aac/aac.c | 134 | ||||
| -rw-r--r-- | sys/dev/aac/aac_cam.c | 10 | ||||
| -rw-r--r-- | sys/dev/aac/aac_cam.h | 34 | ||||
| -rw-r--r-- | sys/dev/aac/aacvar.h | 22 |
4 files changed, 104 insertions, 96 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 0738614f01e40..4f23f1a7e121b 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -83,7 +83,7 @@ static void aac_complete(void *context, int pending); static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp); static void aac_bio_complete(struct aac_command *cm); static int aac_wait_command(struct aac_command *cm, int timeout); -static void aac_host_command(struct aac_softc *sc); +static void aac_command_thread(struct aac_softc *sc); static void aac_host_response(struct aac_softc *sc); /* Command Buffer Management */ @@ -312,10 +312,10 @@ aac_attach(struct aac_softc *sc) /* Create the AIF thread */ #if __FreeBSD_version > 500005 - if (kthread_create((void(*)(void *))aac_host_command, sc, + if (kthread_create((void(*)(void *))aac_command_thread, sc, &sc->aifthread, 0, 0, "aac%daif", unit)) #else - if (kthread_create((void(*)(void *))aac_host_command, sc, + if (kthread_create((void(*)(void *))aac_command_thread, sc, &sc->aifthread, "aac%daif", unit)) #endif panic("Could not create AIF thread\n"); @@ -326,8 +326,10 @@ aac_attach(struct aac_softc *sc) device_printf(sc->aac_dev, "shutdown event registration failed\n"); /* Register with CAM for the non-DASD devices */ - if (!(sc->quirks & AAC_QUIRK_NOCAM)) + if (!(sc->quirks & AAC_QUIRK_NOCAM)) { + TAILQ_INIT(&sc->aac_sim_tqh); aac_get_bus_info(sc); + } return(0); } @@ -383,9 +385,6 @@ aac_startup(void *arg) /* enable interrupts now */ AAC_UNMASK_INTERRUPTS(sc); - - /* enable the timeout watchdog */ - timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz); } /* @@ -484,18 +483,33 @@ int aac_detach(device_t dev) { struct aac_softc *sc; -#if AAC_BROKEN + struct aac_container *co; + struct aac_sim *sim; int error; -#endif debug_called(1); sc = device_get_softc(dev); if (sc->aac_state & AAC_STATE_OPEN) - return(EBUSY); + return(EBUSY); + + /* Remove the child containers */ + TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) { + error = device_delete_child(dev, co->co_disk); + if (error) + return (error); + } + + /* Remove the CAM SIMs */ + TAILQ_FOREACH(sim, &sc->aac_sim_tqh, sim_link) { + error = device_delete_child(dev, sim->sim_dev); + if (error) + return (error); + } + + bus_generic_detach(dev); -#if AAC_BROKEN if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { sc->aifflags |= AAC_AIFFLAGS_EXIT; wakeup(sc->aifthread); @@ -511,9 +525,6 @@ aac_detach(device_t dev) aac_free(sc); return(0); -#else - return (EBUSY); -#endif } /* @@ -556,6 +567,9 @@ aac_shutdown(device_t dev) if (aac_sync_fib(sc, ContainerCommand, 0, fib, sizeof(struct aac_close_command))) printf("FAILED.\n"); + else + printf("done\n"); +#if 0 else { fib->data[0] = 0; /* @@ -571,6 +585,7 @@ aac_shutdown(device_t dev) printf("done.\n"); } } +#endif AAC_MASK_INTERRUPTS(sc); @@ -624,8 +639,8 @@ void aac_intr(void *arg) { struct aac_softc *sc; - u_int16_t reason; u_int32_t *resp_queue; + u_int16_t reason; debug_called(2); @@ -650,17 +665,30 @@ aac_intr(void *arg) aac_host_response(sc); /* controller wants to talk to the log */ - if (reason & AAC_DB_PRINTF) - aac_print_printf(sc); + if (reason & AAC_DB_PRINTF) { + if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { + sc->aifflags |= AAC_AIFFLAGS_PRINTF; + } else + aac_print_printf(sc); + } /* controller has a message for us? */ if (reason & AAC_DB_COMMAND_READY) { - /* XXX What happens if the thread is already awake? */ if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { - sc->aifflags |= AAC_AIFFLAGS_PENDING; - wakeup(sc->aifthread); + sc->aifflags |= AAC_AIFFLAGS_AIF; + } else { + /* + * XXX If the kthread is dead and we're at this point, + * there are bigger problems than just figuring out + * what to do with an AIF. + */ } + } + + if ((sc->aifflags & AAC_AIFFLAGS_PENDING) != 0) + /* XXX Should this be done with cv_signal? */ + wakeup(sc->aifthread); } /* @@ -737,7 +765,7 @@ aac_start(struct aac_command *cm) * Handle notification of one or more FIBs coming from the controller. */ static void -aac_host_command(struct aac_softc *sc) +aac_command_thread(struct aac_softc *sc) { struct aac_fib *fib; u_int32_t fib_size; @@ -748,14 +776,27 @@ aac_host_command(struct aac_softc *sc) sc->aifflags |= AAC_AIFFLAGS_RUNNING; while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) { - if (!(sc->aifflags & AAC_AIFFLAGS_PENDING)) - tsleep(sc->aifthread, PRIBIO, "aifthd", 15 * hz); + if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) + tsleep(sc->aifthread, PRIBIO, "aifthd", + AAC_PERIODIC_INTERVAL * hz); + + /* While we're here, check to see if any commands are stuck */ + if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) + aac_timeout(sc); + + /* Check the hardware printf message buffer */ + if ((sc->aifflags & AAC_AIFFLAGS_PRINTF) != 0) { + sc->aifflags &= ~AAC_AIFFLAGS_PRINTF; + aac_print_printf(sc); + } + + while (sc->aifflags & AAC_AIFFLAGS_AIF) { - sc->aifflags &= ~AAC_AIFFLAGS_PENDING; - for (;;) { if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, - &fib_size, &fib)) + &fib_size, &fib)) { + sc->aifflags &= ~AAC_AIFFLAGS_AIF; break; /* nothing to do */ + } AAC_PRINT_FIB(sc, fib); @@ -769,11 +810,11 @@ aac_host_command(struct aac_softc *sc) break; } - /* Return the AIF to the controller. */ if ((fib->Header.XferState == 0) || (fib->Header.StructType != AAC_FIBTYPE_TFIB)) break; + /* Return the AIF to the controller. */ if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; *(AAC_FSAStatus*)fib->data = ST_OK; @@ -1117,7 +1158,8 @@ aac_alloc_commands(struct aac_softc *sc) /* allocate the FIBs in DMAable memory and load them */ if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs, BUS_DMA_NOWAIT, &sc->aac_fibmap)) { - printf("Not enough contiguous memory available.\n"); + device_printf(sc->aac_dev, + "Not enough contiguous memory available.\n"); return (ENOMEM); } @@ -1805,24 +1847,8 @@ aac_timeout(struct aac_softc *sc) struct aac_command *cm; time_t deadline; -#if 0 - /* simulate an interrupt to handle possibly-missed interrupts */ /* - * XXX This was done to work around another bug which has since been - * fixed. It is dangerous anyways because you don't want multiple - * threads in the interrupt handler at the same time! If calling - * is deamed neccesary in the future, proper mutexes must be used. - */ - s = splbio(); - aac_intr(sc); - splx(s); - - /* kick the I/O queue to restart it in the case of deadlock */ - aac_startio(sc); -#endif - - /* - * traverse the busy command list, bitch about late commands once + * Traverse the busy command list, bitch about late commands once * only. */ deadline = time_second - AAC_CMD_TIMEOUT; @@ -1839,8 +1865,6 @@ aac_timeout(struct aac_softc *sc) } splx(s); - /* reset the timer for next time */ - timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz); return; } @@ -2344,7 +2368,8 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) * Pass the FIB to the controller, wait for it to complete. */ if ((error = aac_wait_command(cm, 30)) != 0) { /* XXX user timeout? */ - printf("aac_wait_command return %d\n", error); + device_printf(sc->aac_dev, + "aac_wait_command return %d\n", error); goto out; } @@ -2448,7 +2473,8 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) /* * This is a new container. Do all the - * appropriate things to set it up. */ + * appropriate things to set it up. + */ aac_add_container(sc, mir, 1); added = 1; } @@ -2612,7 +2638,8 @@ aac_return_aif(struct aac_softc *sc, caddr_t uptr) error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr, sizeof(struct aac_aif_command)); if (error) - printf("aac_return_aif: copyout returned %d\n", error); + device_printf(sc->aac_dev, + "aac_return_aif: copyout returned %d\n", error); if (!error) sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH; @@ -2687,7 +2714,7 @@ aac_get_bus_info(struct aac_softc *sc) struct aac_vmioctl *vmi; struct aac_vmi_businf_resp *vmi_resp; struct aac_getbusinf businfo; - struct aac_cam_inf *caminf; + struct aac_sim *caminf; device_t child; int i, found, error; @@ -2752,8 +2779,8 @@ aac_get_bus_info(struct aac_softc *sc) if (businfo.BusValid[i] != AAC_BUS_VALID) continue; - MALLOC(caminf, struct aac_cam_inf *, - sizeof(struct aac_cam_inf), M_AACBUF, M_NOWAIT | M_ZERO); + MALLOC(caminf, struct aac_sim *, + sizeof(struct aac_sim), M_AACBUF, M_NOWAIT | M_ZERO); if (caminf == NULL) continue; @@ -2770,6 +2797,7 @@ aac_get_bus_info(struct aac_softc *sc) device_set_ivars(child, caminf); device_set_desc(child, "SCSI Passthrough Bus"); + TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link); found = 1; } diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c index 8ece0dd2baa6e..92bb5e889b82e 100644 --- a/sys/dev/aac/aac_cam.c +++ b/sys/dev/aac/aac_cam.c @@ -62,11 +62,10 @@ #include <dev/aac/aacreg.h> #include <dev/aac/aac_ioctl.h> #include <dev/aac/aacvar.h> -#include <dev/aac/aac_cam.h> struct aac_cam { device_t dev; - struct aac_cam_inf *inf; + struct aac_sim *inf; struct cam_sim *sim; struct cam_path *path; }; @@ -114,8 +113,9 @@ aac_cam_probe(device_t dev) static int aac_cam_detach(device_t dev) { + debug_called(2); - return (0); + return (EBUSY); } /* @@ -128,12 +128,12 @@ aac_cam_attach(device_t dev) struct cam_sim *sim; struct cam_path *path; struct aac_cam *camsc; - struct aac_cam_inf *inf; + struct aac_sim *inf; debug_called(1); camsc = (struct aac_cam *)device_get_softc(dev); - inf = (struct aac_cam_inf *)device_get_ivars(dev); + inf = (struct aac_sim *)device_get_ivars(dev); camsc->inf = inf; devq = cam_simq_alloc(inf->TargetsPerBus); diff --git a/sys/dev/aac/aac_cam.h b/sys/dev/aac/aac_cam.h deleted file mode 100644 index b06caeb1fa061..0000000000000 --- a/sys/dev/aac/aac_cam.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2002 Adaptec, Inc. - * 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$ - */ - -struct aac_cam_inf { - int TargetsPerBus; - int BusNumber; - int InitiatorBusId; - struct aac_softc *aac_sc; -}; diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h index 0f615f10944cc..6fcd57dc783ba 100644 --- a/sys/dev/aac/aacvar.h +++ b/sys/dev/aac/aacvar.h @@ -110,6 +110,19 @@ struct aac_container }; /* + * Per-SIM data structure + */ +struct aac_sim +{ + device_t sim_dev; + int TargetsPerBus; + int BusNumber; + int InitiatorBusId; + struct aac_softc *aac_sc; + TAILQ_ENTRY(aac_sim) sim_link; +}; + +/* * Per-disk structure */ struct aac_disk @@ -246,8 +259,6 @@ extern struct aac_interface aac_fa_interface; #define AAC_GETREG1(sc, reg) bus_space_read_1 (sc->aac_btag, \ sc->aac_bhandle, reg) -TAILQ_HEAD(aac_container_tq, aac_container); - /* Define the OS version specific locks */ #if __FreeBSD_version >= 500005 #include <sys/lock.h> @@ -332,7 +343,7 @@ struct aac_softc struct aac_qstat aac_qstat[AACQ_COUNT]; /* queue statistics */ /* connected containters */ - struct aac_container_tq aac_container_tqh; + TAILQ_HEAD(,aac_container) aac_container_tqh; aac_lock_t aac_container_lock; /* Protect the sync fib */ @@ -356,9 +367,11 @@ struct aac_softc struct proc *aifthread; int aifflags; #define AAC_AIFFLAGS_RUNNING (1 << 0) -#define AAC_AIFFLAGS_PENDING (1 << 1) +#define AAC_AIFFLAGS_AIF (1 << 1) #define AAC_AIFFLAGS_EXIT (1 << 2) #define AAC_AIFFLAGS_EXITED (1 << 3) +#define AAC_AIFFLAGS_PRINTF (1 << 4) +#define AAC_AIFFLAGS_PENDING (AAC_AIFFLAGS_AIF | AAC_AIFFLAGS_PRINTF) u_int32_t quirks; #define AAC_QUIRK_PERC2QC (1 << 0) #define AAC_QUIRK_NOCAM (1 << 1) /* No SCSI passthrough */ @@ -366,6 +379,7 @@ struct aac_softc #define AAC_QUIRK_CAM_PASSONLY (1 << 3) /* Only create pass devices */ u_int32_t scsi_method_id; + TAILQ_HEAD(,aac_sim) aac_sim_tqh; }; |
