summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr
diff options
context:
space:
mode:
authoremoore <emoore@FreeBSD.org>2003-01-09 21:02:28 +0000
committeremoore <emoore@FreeBSD.org>2003-01-09 21:02:28 +0000
commite7d622d221d2507a346a2e63a6fde4165a9896e1 (patch)
treee1f469d832bb3b164f1c193f335ca8c70f57a195 /sys/dev/amr
parent7ae476eef2288f8f8019269b538411c7d8ec791c (diff)
downloadFreeBSD-src-e7d622d221d2507a346a2e63a6fde4165a9896e1.zip
FreeBSD-src-e7d622d221d2507a346a2e63a6fde4165a9896e1.tar.gz
Fix for DELL PERC firmware. Driver was hanging
during load time; this attributed to the mailbox busy byte not being set prior to issuing a polling command. Approved by: ps MFC: 7 days
Diffstat (limited to 'sys/dev/amr')
-rw-r--r--sys/dev/amr/amr.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index a95e78b..e75c2af 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -977,7 +977,7 @@ amr_quartz_poll_command(struct amr_command *ac)
{
struct amr_softc *sc = ac->ac_sc;
int s;
- int error;
+ int error,count;
debug_called(2);
@@ -986,8 +986,16 @@ amr_quartz_poll_command(struct amr_command *ac)
s = splbio();
+ count=0;
+ while (sc->amr_busyslots){
+ tsleep(sc, PRIBIO | PCATCH, "amrpoll", hz);
+ if(count++>10) {
+ break;
+ }
+ }
+
if(sc->amr_busyslots) {
- device_printf(sc->amr_dev, "adapter is busy");
+ device_printf(sc->amr_dev, "adapter is busy\n");
splx(s);
amr_unmapcmd(ac);
ac->ac_status=0;
@@ -1002,6 +1010,7 @@ amr_quartz_poll_command(struct amr_command *ac)
sc->amr_mailbox->mb_status = 0xFF;
sc->amr_mailbox->mb_poll = 0;
sc->amr_mailbox->mb_ack = 0;
+ sc->amr_mailbox->mb_busy = 1;
AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
@@ -1015,6 +1024,7 @@ amr_quartz_poll_command(struct amr_command *ac)
/* acknowledge that we have the commands */
AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
+ while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
splx(s);
@@ -1403,6 +1413,10 @@ amr_complete(void *context, int pending)
} else if (ac->ac_flags & AMR_CMD_SLEEP) {
wakeup(ac);
}
+
+ if(!sc->amr_busyslots) {
+ wakeup(sc);
+ }
}
}
OpenPOWER on IntegriCloud