diff options
author | Eric Moore <emoore@FreeBSD.org> | 2002-12-11 20:59:46 +0000 |
---|---|---|
committer | Eric Moore <emoore@FreeBSD.org> | 2002-12-11 20:59:46 +0000 |
commit | d6b32def6c61c428076df93608fb866e10078dcc (patch) | |
tree | 426e232feefcc8a33a07b7c836ee1b8494879e60 /sys | |
parent | a5297d2a512c5cb1c1b689c3792036e843c7a143 (diff) | |
download | src-d6b32def6c61c428076df93608fb866e10078dcc.tar.gz src-d6b32def6c61c428076df93608fb866e10078dcc.zip |
(1) Problem: PANIC when loading/unloading driver
as module. This also fix's issue kern/45713.
Fix - polling was implemented incorrectly for
adapter enquiry and adapter flush.
(2) Problem: PANIC when unloading driver
as module.
Fix - device nodes are not destroyed for amr0,
and amrd* when driver is unloaded
(3) Problem: PANIC from loading driver when
3ware adapter present, error message "Warning
"amrd is usurping twed's bmaj"
Fix - put #idef freebsd version < 500000 for
bmaj -1 -> amrd_cdevsw
(4) Problem: warnings in driver when compiling
with DAMR_DEBUG param enabled in Makefile
Fix - fix the warnings so driver can compile
when -Werror is present in Makefile.
Approved by: jhb
MFC: 7 days
Notes
Notes:
svn path=/head/; revision=107756
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/amr/amr.c | 79 | ||||
-rw-r--r-- | sys/dev/amr/amr_cam.c | 2 | ||||
-rw-r--r-- | sys/dev/amr/amr_disk.c | 3 | ||||
-rw-r--r-- | sys/dev/amr/amr_pci.c | 19 | ||||
-rw-r--r-- | sys/dev/amr/amrvar.h | 3 |
5 files changed, 95 insertions, 11 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index 6db7d77ae633..59a83f809f82 100644 --- a/sys/dev/amr/amr.c +++ b/sys/dev/amr/amr.c @@ -134,7 +134,6 @@ static void amr_freecmd_cluster(struct amr_command_cluster *acc); */ static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); static int amr_wait_command(struct amr_command *ac); -static int amr_poll_command(struct amr_command *ac); static int amr_getslot(struct amr_command *ac); static void amr_mapcmd(struct amr_command *ac); static void amr_unmapcmd(struct amr_command *ac); @@ -151,9 +150,11 @@ static void amr_periodic(void *data); */ static int amr_quartz_submit_command(struct amr_softc *sc); static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); +static int amr_quartz_poll_command(struct amr_command *ac); static int amr_std_submit_command(struct amr_softc *sc); static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); +static int amr_std_poll_command(struct amr_command *ac); static void amr_std_attach_mailbox(struct amr_softc *sc); #ifdef AMR_BOARD_INIT @@ -166,8 +167,10 @@ static int amr_std_init(struct amr_softc *sc); */ static void amr_describe_controller(struct amr_softc *sc); #ifdef AMR_DEBUG +#if 0 static void amr_printcommand(struct amr_command *ac); #endif +#endif /******************************************************************************** ******************************************************************************** @@ -214,9 +217,11 @@ amr_attach(struct amr_softc *sc) if (AMR_IS_QUARTZ(sc)) { sc->amr_submit_command = amr_quartz_submit_command; sc->amr_get_work = amr_quartz_get_work; + sc->amr_poll_command = amr_quartz_poll_command; } else { sc->amr_submit_command = amr_std_submit_command; sc->amr_get_work = amr_std_get_work; + sc->amr_poll_command = amr_std_poll_command; amr_std_attach_mailbox(sc);; } @@ -336,7 +341,7 @@ amr_free(struct amr_softc *sc) struct amr_command_cluster *acc; /* detach from CAM */ - amr_cam_detach(sc); + amr_cam_detach(sc); /* cancel status timeout */ untimeout(amr_periodic, sc, sc->amr_timeout); @@ -346,6 +351,10 @@ amr_free(struct amr_softc *sc) TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link); amr_freecmd_cluster(acc); } + + /* destroy control device */ + if( sc->amr_dev_t != (dev_t)NULL) + destroy_dev(sc->amr_dev_t); } /******************************************************************************* @@ -502,7 +511,7 @@ amr_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) error = copyout(dp, au->au_buffer, au->au_length); debug(2, "copyout %ld bytes from %p -> %p", au->au_length, dp, au->au_buffer); if (dp != NULL) - debug(2, "%16D", dp, " "); + debug(2, "%16d", (int)dp); au->au_status = ac->ac_status; break; @@ -689,7 +698,7 @@ amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, mbox[3] = cmdqual; /* can't assume that interrupts are going to work here, so play it safe */ - if (amr_poll_command(ac)) + if (sc->amr_poll_command(ac)) goto out; error = ac->ac_status; @@ -723,7 +732,7 @@ amr_flush(struct amr_softc *sc) ac->ac_mailbox.mb_command = AMR_CMD_FLUSH; /* we have to poll, as the system may be going down or otherwise damaged */ - if (amr_poll_command(ac)) + if (sc->amr_poll_command(ac)) goto out; error = ac->ac_status; @@ -759,7 +768,7 @@ amr_support_ext_cdb(struct amr_softc *sc) /* we have to poll, as the system may be going down or otherwise damaged */ - if (amr_poll_command(ac)) + if (sc->amr_poll_command(ac)) goto out; if( ac->ac_status == AMR_STATUS_SUCCESS ) { error = 1; @@ -929,7 +938,7 @@ amr_wait_command(struct amr_command *ac) * Returns nonzero on error. Can be safely called with interrupts enabled. */ static int -amr_poll_command(struct amr_command *ac) +amr_std_poll_command(struct amr_command *ac) { struct amr_softc *sc = ac->ac_sc; int error, count; @@ -960,6 +969,60 @@ amr_poll_command(struct amr_command *ac) } /******************************************************************************** + * Take a command, submit it to the controller and busy-wait for it to return. + * Returns nonzero on error. Can be safely called with interrupts enabled. + */ +static int +amr_quartz_poll_command(struct amr_command *ac) +{ + struct amr_softc *sc = ac->ac_sc; + int s; + + debug_called(2); + + /* now we have a slot, we can map the command (unmapped in amr_complete) */ + amr_mapcmd(ac); + + s = splbio(); + + if(sc->amr_busyslots) { + device_printf(sc->amr_dev, "adapter is busy"); + splx(s); + amr_unmapcmd(ac); + ac->ac_status=0; + return(1); + } + + bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); + + /* clear the poll/ack fields in the mailbox */ + sc->amr_mailbox->mb_ident = 0xFE; + sc->amr_mailbox->mb_nstatus = 0xFF; + sc->amr_mailbox->mb_status = 0xFF; + sc->amr_mailbox->mb_poll = 0; + sc->amr_mailbox->mb_ack = 0; + + AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT); + + while(sc->amr_mailbox->mb_nstatus == 0xFF); + while(sc->amr_mailbox->mb_status == 0xFF); + while(sc->amr_mailbox->mb_poll != 0x77); + sc->amr_mailbox->mb_poll = 0; + sc->amr_mailbox->mb_ack = 0x77; + + /* acknowledge that we have the commands */ + AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); + + splx(s); + + /* unmap the command's data buffer */ + amr_unmapcmd(ac); + + ac->ac_status=0; + return(0); +} + +/******************************************************************************** * Get a free command slot for a command if it doesn't already have one. * * May be safely called multiple times for a given command. @@ -1713,6 +1776,7 @@ amr_describe_controller(struct amr_softc *sc) /******************************************************************************** * Print the command (ac) in human-readable format */ +#if 0 static void amr_printcommand(struct amr_command *ac) { @@ -1735,3 +1799,4 @@ amr_printcommand(struct amr_command *ac) device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count); } #endif +#endif diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c index 37412b6d5a8d..603a751e6591 100644 --- a/sys/dev/amr/amr_cam.c +++ b/sys/dev/amr/amr_cam.c @@ -580,7 +580,7 @@ amr_cam_complete_extcdb(struct amr_command *ac) /* XXX note that we're ignoring ac->ac_status - good idea? */ - debug(1, "status 0x%x scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status); + debug(1, "status 0x%x scsi_status 0x%x", ac->ac_status, aep->ap_scsi_status); /* * Hide disks from CAM so that they're not picked up and treated as 'normal' disks. diff --git a/sys/dev/amr/amr_disk.c b/sys/dev/amr/amr_disk.c index d6d139a0c41d..1aa1fc68536d 100644 --- a/sys/dev/amr/amr_disk.c +++ b/sys/dev/amr/amr_disk.c @@ -105,6 +105,9 @@ static struct cdevsw amrd_cdevsw = { /* dump */ nodump, /* psize */ nopsize, /* flags */ D_DISK, +#if __FreeBSD_version < 500000 + /* bmaj */ -1 +#endif }; static devclass_t amrd_devclass; diff --git a/sys/dev/amr/amr_pci.c b/sys/dev/amr/amr_pci.c index 7fcc6d4c2e0b..f870d4cbbc5c 100644 --- a/sys/dev/amr/amr_pci.c +++ b/sys/dev/amr/amr_pci.c @@ -337,6 +337,7 @@ static int amr_pci_shutdown(device_t dev) { struct amr_softc *sc = device_get_softc(dev); + int i,error,s; debug_called(1); @@ -348,9 +349,23 @@ amr_pci_shutdown(device_t dev) device_printf(sc->amr_dev, "flushing cache..."); printf("%s\n", amr_flush(sc) ? "failed" : "done"); + s = splbio(); + error = 0; + + /* delete all our child devices */ + for(i = 0 ; i < AMR_MAXLD; i++) { + if( sc->amr_drive[i].al_disk != 0) { + if((error = device_delete_child(sc->amr_dev,sc->amr_drive[i].al_disk)) != 0) + goto shutdown_out; + sc->amr_drive[i].al_disk = 0; + } + } + /* XXX disable interrupts? */ - - return(0); + +shutdown_out: + splx(s); + return(error); } /******************************************************************************** diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h index d3e1e8875710..1c9884f2b272 100644 --- a/sys/dev/amr/amrvar.h +++ b/sys/dev/amr/amrvar.h @@ -211,7 +211,8 @@ struct amr_softc #define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD) int (* amr_submit_command)(struct amr_softc *sc); int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave); - int support_ext_cdb; /* greater than 10 byte cdb support */ + int (*amr_poll_command)(struct amr_command *ac); + int support_ext_cdb; /* greater than 10 byte cdb support */ /* misc glue */ struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */ |