From b367b3b6f607fd4fbe13694abff262b268ab7da7 Mon Sep 17 00:00:00 2001 From: scottl Date: Wed, 2 Jun 2004 18:15:48 +0000 Subject: Collapse sync fib locking into normal i/o locking. The former didn't protect the registers so it was trivially possible for a sync command and i/o command to fight each other and confuse the controller. Make the sync fib alloc/release functions inline and remove the somewhat worthless AAC_SYNC_LOCK_FORCE flag. Thanks to Adil Katchi for helping me to track this down in RELENG_4. --- sys/dev/aac/aac.c | 43 +++++-------------------------------------- sys/dev/aac/aac_cam.c | 4 ++-- sys/dev/aac/aac_disk.c | 3 ++- sys/dev/aac/aacvar.h | 28 +++++++++++++++++++++------- 4 files changed, 30 insertions(+), 48 deletions(-) (limited to 'sys') diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 73802e8..9a09cf8 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -236,7 +236,6 @@ aac_attach(struct aac_softc *sc) /* * Initialize locks */ - AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock"); AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock"); AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock"); AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock"); @@ -316,7 +315,7 @@ aac_startup(void *arg) /* disconnect ourselves from the intrhook chain */ config_intrhook_disestablish(&sc->aac_ich); - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); mi = (struct aac_mntinfo *)&fib->data[0]; /* loop over possible containers */ @@ -526,7 +525,7 @@ aac_shutdown(device_t dev) */ device_printf(sc->aac_dev, "shutting down controller..."); - aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE); + aac_alloc_sync_fib(sc, &fib); cc = (struct aac_close_command *)&fib->data[0]; bzero(cc, sizeof(struct aac_close_command)); @@ -1690,38 +1689,6 @@ aac_sync_command(struct aac_softc *sc, u_int32_t command, return(0); } -/* - * Grab the sync fib area. - */ -int -aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags) -{ - - /* - * If the force flag is set, the system is shutting down, or in - * trouble. Ignore the mutex. - */ - if (!(flags & AAC_SYNC_LOCK_FORCE)) - AAC_LOCK_ACQUIRE(&sc->aac_sync_lock); - - *fib = &sc->aac_common->ac_sync_fib; - - return (1); -} - -/* - * Release the sync fib area. - */ -void -aac_release_sync_fib(struct aac_softc *sc) -{ - - AAC_LOCK_RELEASE(&sc->aac_sync_lock); -} - -/* - * Send a synchronous FIB to the controller and wait for a result. - */ int aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, struct aac_fib *fib, u_int16_t datasize) @@ -2267,7 +2234,7 @@ aac_describe_controller(struct aac_softc *sc) debug_called(2); - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); fib->data[0] = 0; if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { @@ -2588,7 +2555,7 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) * doesn't tell us anything else! Re-enumerate the * containers and sort things out. */ - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); mi = (struct aac_mntinfo *)&fib->data[0]; do { /* @@ -2883,7 +2850,7 @@ aac_get_bus_info(struct aac_softc *sc) device_t child; int i, found, error; - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); c_cmd = (struct aac_ctcfg *)&fib->data[0]; bzero(c_cmd, sizeof(struct aac_ctcfg)); diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c index d82439e..ffe322b 100644 --- a/sys/dev/aac/aac_cam.c +++ b/sys/dev/aac/aac_cam.c @@ -523,7 +523,7 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb) return (CAM_REQ_ABORTED); } - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); vmi = (struct aac_vmioctl *)&fib->data[0]; bzero(vmi, sizeof(struct aac_vmioctl)); @@ -570,7 +570,7 @@ aac_cam_get_tran_settings(struct aac_softc *sc, struct ccb_trans_settings *cts, struct aac_vmi_devinfo_resp *vmi_resp; int error; - aac_alloc_sync_fib(sc, &fib, 0); + aac_alloc_sync_fib(sc, &fib); vmi = (struct aac_vmioctl *)&fib->data[0]; bzero(vmi, sizeof(struct aac_vmioctl)); diff --git a/sys/dev/aac/aac_disk.c b/sys/dev/aac/aac_disk.c index 9316a4f..a52b7bb 100644 --- a/sys/dev/aac/aac_disk.c +++ b/sys/dev/aac/aac_disk.c @@ -246,7 +246,8 @@ aac_disk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size } } - aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE); + /* Skip aac_alloc_sync_fib(). We don't want to mess with sleep locks */ + fib = &sc->aac_common->ac_sync_fib; bw = (struct aac_blockwrite *)&fib->data[0]; while (length > 0) { diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h index 8d40849..bedc6b0 100644 --- a/sys/dev/aac/aacvar.h +++ b/sys/dev/aac/aacvar.h @@ -332,10 +332,10 @@ struct aac_softc TAILQ_HEAD(,aac_container) aac_container_tqh; aac_lock_t aac_container_lock; - /* Protect the sync fib */ -#define AAC_SYNC_LOCK_FORCE (1 << 0) - aac_lock_t aac_sync_lock; - + /* + * The general I/O lock. This protects the sync fib, the lists, the + * queues, and the registers. + */ aac_lock_t aac_io_lock; /* delayed activity infrastructure */ @@ -395,9 +395,6 @@ extern void aac_startio(struct aac_softc *sc); extern int aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp); extern void aac_release_command(struct aac_command *cm); -extern int aac_alloc_sync_fib(struct aac_softc *sc, - struct aac_fib **fib, int flags); -extern void aac_release_sync_fib(struct aac_softc *sc); extern int aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, struct aac_fib *fib, u_int16_t datasize); @@ -574,3 +571,20 @@ aac_print_printf(struct aac_softc *sc) sc->aac_common->ac_printf[0] = 0; AAC_QNOTIFY(sc, AAC_DB_PRINTF); } + +static __inline int +aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib) +{ + + AAC_LOCK_ACQUIRE(&sc->aac_io_lock); + *fib = &sc->aac_common->ac_sync_fib; + return (0); +} + +static __inline void +aac_release_sync_fib(struct aac_softc *sc) +{ + + AAC_LOCK_RELEASE(&sc->aac_io_lock); +} + -- cgit v1.1