(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
This commit is contained in:
Eric Moore 2002-12-11 20:59:46 +00:00
parent a5297d2a51
commit d6b32def6c
5 changed files with 95 additions and 11 deletions

View File

@ -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;
@ -959,6 +968,60 @@ amr_poll_command(struct amr_command *ac)
return(error);
}
/********************************************************************************
* 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.
*
@ -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

View File

@ -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.

View File

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

View File

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

View File

@ -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 */