(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:
parent
a5297d2a51
commit
d6b32def6c
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user