summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr
diff options
context:
space:
mode:
authoremoore <emoore@FreeBSD.org>2002-12-11 20:59:46 +0000
committeremoore <emoore@FreeBSD.org>2002-12-11 20:59:46 +0000
commit90d1dfac3c8a6c5d89483c467b979235b151deb7 (patch)
tree426e232feefcc8a33a07b7c836ee1b8494879e60 /sys/dev/amr
parenta4e4df0035b743eedbc9d753c657bdbc6e54db97 (diff)
downloadFreeBSD-src-90d1dfac3c8a6c5d89483c467b979235b151deb7.zip
FreeBSD-src-90d1dfac3c8a6c5d89483c467b979235b151deb7.tar.gz
(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
Diffstat (limited to 'sys/dev/amr')
-rw-r--r--sys/dev/amr/amr.c79
-rw-r--r--sys/dev/amr/amr_cam.c2
-rw-r--r--sys/dev/amr/amr_disk.c3
-rw-r--r--sys/dev/amr/amr_pci.c19
-rw-r--r--sys/dev/amr/amrvar.h3
5 files changed, 95 insertions, 11 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index 6db7d77..59a83f8 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 37412b6..603a751 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 d6d139a..1aa1fc6 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 7fcc6d4..f870d4c 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 d3e1e88..1c9884f 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 */
OpenPOWER on IntegriCloud