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.
This commit is contained in:
Scott Long 2004-06-02 18:15:48 +00:00
parent 9455fe9a67
commit 03b5fe51bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=130006
4 changed files with 30 additions and 48 deletions

View File

@ -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));

View File

@ -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));

View File

@ -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) {

View File

@ -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);
}