aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/isp
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2017-03-14 08:03:56 +0000
committerAlexander Motin <mav@FreeBSD.org>2017-03-14 08:03:56 +0000
commita1fa02673afaed21473adc4633faac57b554acc0 (patch)
tree17548ba20920729ca4bef84e31cb17e11b357cb7 /sys/dev/isp
parent3667f39ea3bcb716a7e6dc3ebd973e4cac6980f0 (diff)
Notes
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp.c192
-rw-r--r--sys/dev/isp/isp_freebsd.c17
-rw-r--r--sys/dev/isp/isp_freebsd.h1
-rw-r--r--sys/dev/isp/isp_library.c22
-rw-r--r--sys/dev/isp/isp_library.h5
-rw-r--r--sys/dev/isp/isp_pci.c290
-rw-r--r--sys/dev/isp/isp_sbus.c154
-rw-r--r--sys/dev/isp/ispvar.h24
8 files changed, 314 insertions, 391 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 44281cec608c0..87c1dd9460725 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -178,13 +178,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
const char *btype = "????";
static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
- isp->isp_state = ISP_NILSTATE;
- if (isp->isp_dead) {
- isp_shutdown(isp);
- ISP_DISABLE_INTS(isp);
- return;
- }
-
/*
* Basic types (SCSI, FibreChannel and PCI or SBus)
* have been set in the MD code. We figure out more
@@ -195,56 +188,10 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
* for SCSI adapters and do other settings for the 2100.
*/
+ isp->isp_state = ISP_NILSTATE;
ISP_DISABLE_INTS(isp);
/*
- * Pick an initial maxcmds value which will be used
- * to allocate xflist pointer space. It may be changed
- * later by the firmware.
- */
- if (IS_24XX(isp)) {
- isp->isp_maxcmds = 4096;
- } else if (IS_2322(isp)) {
- isp->isp_maxcmds = 2048;
- } else if (IS_23XX(isp) || IS_2200(isp)) {
- isp->isp_maxcmds = 1024;
- } else {
- isp->isp_maxcmds = 512;
- }
-
- /*
- * Set up DMA for the request and response queues.
- *
- * We do this now so we can use the request queue
- * for dma to load firmware from.
- */
- if (ISP_MBOXDMASETUP(isp) != 0) {
- isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
- return;
- }
-
- /*
- * Set up default request/response queue in-pointer/out-pointer
- * register indices.
- */
- if (IS_24XX(isp)) {
- isp->isp_rqstinrp = BIU2400_REQINP;
- isp->isp_rqstoutrp = BIU2400_REQOUTP;
- isp->isp_respinrp = BIU2400_RSPINP;
- isp->isp_respoutrp = BIU2400_RSPOUTP;
- } else if (IS_23XX(isp)) {
- isp->isp_rqstinrp = BIU_REQINP;
- isp->isp_rqstoutrp = BIU_REQOUTP;
- isp->isp_respinrp = BIU_RSPINP;
- isp->isp_respoutrp = BIU_RSPOUTP;
- } else {
- isp->isp_rqstinrp = INMAILBOX4;
- isp->isp_rqstoutrp = OUTMAILBOX4;
- isp->isp_respinrp = OUTMAILBOX5;
- isp->isp_respoutrp = INMAILBOX5;
- }
-
- /*
* Put the board into PAUSE mode (so we can read the SXP registers
* or write FPM/FBM registers).
*/
@@ -468,7 +415,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp->isp_clock = isp->isp_mdvec->dv_clock;
}
}
-
}
/*
@@ -477,11 +423,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp->isp_intcnt = isp->isp_intbogus = 0;
/*
- * Do MD specific pre initialization
- */
- ISP_RESET0(isp);
-
- /*
* Hit the chip over the head with hammer,
* and give it a chance to recover.
*/
@@ -513,7 +454,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
}
}
if (val & BIU2400_DMA_ACTIVE) {
- ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
return;
}
@@ -533,7 +473,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
}
}
if (val & BIU2400_SOFT_RESET) {
- ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
return;
}
@@ -572,7 +511,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
ISP_DELAY(100);
if (--loops < 0) {
ISP_DUMPREGS(isp, "chip reset timed out");
- ISP_RESET0(isp);
return;
}
}
@@ -613,7 +551,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
}
}
if (val != 0) {
- ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR, "reset didn't clear");
return;
}
@@ -655,6 +592,26 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
}
+ /*
+ * Set up default request/response queue in-pointer/out-pointer
+ * register indices.
+ */
+ if (IS_24XX(isp)) {
+ isp->isp_rqstinrp = BIU2400_REQINP;
+ isp->isp_rqstoutrp = BIU2400_REQOUTP;
+ isp->isp_respinrp = BIU2400_RSPINP;
+ isp->isp_respoutrp = BIU2400_RSPOUTP;
+ } else if (IS_23XX(isp)) {
+ isp->isp_rqstinrp = BIU_REQINP;
+ isp->isp_rqstoutrp = BIU_REQOUTP;
+ isp->isp_respinrp = BIU_RSPINP;
+ isp->isp_respoutrp = BIU_RSPOUTP;
+ } else {
+ isp->isp_rqstinrp = INMAILBOX4;
+ isp->isp_rqstoutrp = OUTMAILBOX4;
+ isp->isp_respinrp = OUTMAILBOX5;
+ isp->isp_respoutrp = INMAILBOX5;
+ }
ISP_WRITE(isp, isp->isp_rqstinrp, 0);
ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
ISP_WRITE(isp, isp->isp_respinrp, 0);
@@ -668,10 +625,10 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
}
- /*
- * Do MD specific post initialization
- */
- ISP_RESET1(isp);
+ if (!IS_24XX(isp) && isp->isp_bustype == ISP_BT_PCI) {
+ /* Make sure the BIOS is disabled */
+ ISP_WRITE(isp, HCCR, PCI_HCCR_CMD_BIOS);
+ }
/*
* Wait for everything to finish firing up.
@@ -686,7 +643,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
ISP_DELAY(100);
if (--loops < 0) {
- ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR, "MBOX_BUSY never cleared on reset");
return;
}
@@ -707,14 +663,12 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
- ISP_RESET0(isp);
return;
}
/*
* Do some operational tests
*/
-
if (IS_SCSI(isp) || IS_24XX(isp)) {
static const uint16_t patterns[MAX_MAILBOX] = {
0x0000, 0xdead, 0xbeef, 0xffff,
@@ -735,12 +689,10 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
}
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- ISP_RESET0(isp);
return;
}
for (i = 1; i < nmbox; i++) {
if (mbs.param[i] != patterns[i]) {
- ISP_RESET0(isp);
isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]);
return;
}
@@ -758,6 +710,17 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
*/
if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
dodnld = 0;
+ } else {
+
+ /*
+ * Set up DMA for the request and response queues.
+ * We do this now so we can use the request queue
+ * for dma to load firmware from.
+ */
+ if (ISP_MBOXDMASETUP(isp) != 0) {
+ isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
+ return;
+ }
}
if (IS_24XX(isp)) {
@@ -849,7 +812,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
goto again;
}
isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
- ISP_RESET0(isp);
return;
}
la += nw;
@@ -918,7 +880,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
- ISP_RESET0(isp);
return;
}
la += nw;
@@ -961,7 +922,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
- ISP_RESET0(isp);
return;
}
} else if (IS_26XX(isp)) {
@@ -971,7 +931,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
- ISP_RESET0(isp);
return;
}
} else {
@@ -992,7 +951,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
isp_prt(isp, ISP_LOGERR, dcrc);
- ISP_RESET0(isp);
return;
}
}
@@ -1003,8 +961,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
* If we didn't actually download f/w,
* we still need to (re)start it.
*/
-
-
MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000);
if (IS_24XX(isp)) {
mbs.param[1] = code_org >> 16;
@@ -1027,7 +983,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp_mboxcmd(isp, &mbs);
if (IS_2322(isp) || IS_24XX(isp)) {
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- ISP_RESET0(isp);
return;
}
}
@@ -1051,7 +1006,6 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- ISP_RESET0(isp);
return;
}
@@ -1249,22 +1203,16 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- ISP_RESET0(isp);
return;
}
- if (isp->isp_maxcmds >= mbs.param[3]) {
- isp->isp_maxcmds = mbs.param[3];
- }
+ isp->isp_maxcmds = mbs.param[3];
} else {
MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
isp_mboxcmd(isp, &mbs);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- ISP_RESET0(isp);
return;
}
- if (isp->isp_maxcmds >= mbs.param[2]) {
- isp->isp_maxcmds = mbs.param[2];
- }
+ isp->isp_maxcmds = mbs.param[2];
}
isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
@@ -1284,15 +1232,28 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
isp->isp_nchan = 1;
}
}
+
+ /*
+ * Final DMA setup after we got isp_maxcmds.
+ */
+ if (ISP_MBOXDMASETUP(isp) != 0) {
+ isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
+ return;
+ }
+
+ /*
+ * Setup interrupts.
+ */
+ if (ISP_IRQSETUP(isp) != 0) {
+ isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
+ return;
+ }
+ ISP_ENABLE_INTS(isp);
+
if (IS_FC(isp)) {
for (i = 0; i < isp->isp_nchan; i++)
isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
}
- if (isp->isp_dead) {
- isp_shutdown(isp);
- ISP_DISABLE_INTS(isp);
- return;
- }
isp->isp_state = ISP_RESETSTATE;
@@ -1303,7 +1264,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
* of knowing how many luns we support.
*
* Expanded lun firmware gives you 32 luns for SCSI cards and
- * 16384 luns for Fibre Channel cards.
+ * unlimited luns for Fibre Channel cards.
*
* It turns out that even for QLogic 2100s with ROM 1.10 and above
* we do get a firmware attributes word returned in mailbox register 6.
@@ -1351,7 +1312,7 @@ isp_reset(ispsoftc_t *isp, int do_load_defaults)
* Clean firmware shutdown.
*/
static int
-isp_deinit(ispsoftc_t *isp)
+isp_stop(ispsoftc_t *isp)
{
mbreg_t mbs;
@@ -1370,6 +1331,35 @@ isp_deinit(ispsoftc_t *isp)
}
/*
+ * Hardware shutdown.
+ */
+void
+isp_shutdown(ispsoftc_t *isp)
+{
+
+ if (isp->isp_state >= ISP_RESETSTATE)
+ isp_stop(isp);
+ ISP_DISABLE_INTS(isp);
+ if (IS_FC(isp)) {
+ if (IS_24XX(isp)) {
+ ISP_WRITE(isp, BIU2400_ICR, 0);
+ ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
+ } else {
+ ISP_WRITE(isp, BIU_ICR, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+ ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+ ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+ ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+ }
+ } else {
+ ISP_WRITE(isp, BIU_ICR, 0);
+ ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+ }
+}
+
+/*
* Initialize Parameters of Hardware to a known state.
*
* Locks are held before coming here.
@@ -5599,7 +5589,6 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
isp_async(isp, ISPASYNC_BUS_RESET, chan);
break;
case ASYNC_SYSTEM_ERROR:
- isp->isp_dead = 1;
isp->isp_state = ISP_CRASHED;
/*
* Were we waiting for a mailbox command to complete?
@@ -5770,7 +5759,6 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
switch (mbox) {
case ASYNC_SYSTEM_ERROR:
- isp->isp_dead = 1;
isp->isp_state = ISP_CRASHED;
FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
@@ -6052,7 +6040,6 @@ isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
"Point-to-Point -> Loop mode (BAD LIP)");
break;
case ISP_CONN_FATAL:
- isp->isp_dead = 1;
isp->isp_state = ISP_CRASHED;
isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
isp_async(isp, ISPASYNC_FW_CRASH);
@@ -7895,14 +7882,13 @@ isp_reinit(ispsoftc_t *isp, int do_load_defaults)
{
int i, res = 0;
- if (isp->isp_state == ISP_RUNSTATE)
- isp_deinit(isp);
+ if (isp->isp_state > ISP_RESETSTATE)
+ isp_stop(isp);
if (isp->isp_state != ISP_RESETSTATE)
isp_reset(isp, do_load_defaults);
if (isp->isp_state != ISP_RESETSTATE) {
res = EIO;
isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
- ISP_DISABLE_INTS(isp);
goto cleanup;
}
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index ba66cf6fee645..9009fa21f080b 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1529,7 +1529,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests,
(uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length);
cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length;
- if (isp->isp_osinfo.sixtyfourbit) {
+ if (cto->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_base = DMA_LO32(addr);
cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_basehi = DMA_HI32(addr);
cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length;
@@ -4304,21 +4304,6 @@ changed:
}
}
-
-/*
- * Locks are held before coming here.
- */
-void
-isp_uninit(ispsoftc_t *isp)
-{
- if (IS_24XX(isp)) {
- ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
- } else {
- ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
- }
- ISP_DISABLE_INTS(isp);
-}
-
uint64_t
isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn)
{
diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h
index f3c6df3269954..06d8236e389c4 100644
--- a/sys/dev/isp/isp_freebsd.h
+++ b/sys/dev/isp/isp_freebsd.h
@@ -697,7 +697,6 @@ default: \
*/
extern int isp_attach(ispsoftc_t *);
extern int isp_detach(ispsoftc_t *);
-extern void isp_uninit(ispsoftc_t *);
extern uint64_t isp_default_wwn(ispsoftc_t *, int, int, int);
/*
diff --git a/sys/dev/isp/isp_library.c b/sys/dev/isp/isp_library.c
index f186e50b23951..d46593e383d89 100644
--- a/sys/dev/isp/isp_library.c
+++ b/sys/dev/isp/isp_library.c
@@ -632,28 +632,6 @@ isp_clear_commands(ispsoftc_t *isp)
#endif
}
-void
-isp_shutdown(ispsoftc_t *isp)
-{
- if (IS_FC(isp)) {
- if (IS_24XX(isp)) {
- ISP_WRITE(isp, BIU2400_ICR, 0);
- ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
- } else {
- ISP_WRITE(isp, BIU_ICR, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
- ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
- ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
- ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
- }
- } else {
- ISP_WRITE(isp, BIU_ICR, 0);
- ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
- }
-}
-
/*
* Functions to move stuff to a form that the QLogic RISC engine understands
* and functions to move stuff back to a form the processor understands.
diff --git a/sys/dev/isp/isp_library.h b/sys/dev/isp/isp_library.h
index c70b2ccda01d0..7b90e3e10428a 100644
--- a/sys/dev/isp/isp_library.h
+++ b/sys/dev/isp/isp_library.h
@@ -77,11 +77,6 @@ const char *isp_fc_toponame(fcparam *);
void isp_clear_commands(ispsoftc_t *);
/*
- * Common chip shutdown function
- */
-void isp_shutdown(ispsoftc_t *);
-
-/*
* Put/Get routines to push from CPU view to device view
* or to pull from device view to CPU view for various
* data structures (IOCB)
diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c
index 8a51cf511a757..bb1322a89fff5 100644
--- a/sys/dev/isp/isp_pci.c
+++ b/sys/dev/isp/isp_pci.c
@@ -65,11 +65,9 @@ static int isp_pci_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_pci_rd_isr_2300(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_pci_rd_isr_2400(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_pci_mbxdma(ispsoftc_t *);
+static void isp_pci_mbxdmafree(ispsoftc_t *);
static int isp_pci_dmasetup(ispsoftc_t *, XS_T *, void *);
-
-
-static void isp_pci_reset0(ispsoftc_t *);
-static void isp_pci_reset1(ispsoftc_t *);
+static int isp_pci_irqsetup(ispsoftc_t *);
static void isp_pci_dumpregs(ispsoftc_t *, const char *);
static struct ispmdvec mdvec = {
@@ -79,8 +77,7 @@ static struct ispmdvec mdvec = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs,
NULL,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
@@ -93,8 +90,7 @@ static struct ispmdvec mdvec_1080 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs,
NULL,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
@@ -107,8 +103,7 @@ static struct ispmdvec mdvec_12160 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs,
NULL,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
@@ -121,8 +116,7 @@ static struct ispmdvec mdvec_2100 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs
};
@@ -133,8 +127,7 @@ static struct ispmdvec mdvec_2200 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs
};
@@ -145,8 +138,7 @@ static struct ispmdvec mdvec_2300 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
isp_pci_dumpregs
};
@@ -157,8 +149,7 @@ static struct ispmdvec mdvec_2400 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
NULL
};
@@ -169,8 +160,7 @@ static struct ispmdvec mdvec_2500 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
NULL
};
@@ -181,8 +171,7 @@ static struct ispmdvec mdvec_2600 = {
isp_pci_mbxdma,
isp_pci_dmasetup,
isp_common_dmateardown,
- isp_pci_reset0,
- isp_pci_reset1,
+ isp_pci_irqsetup,
NULL
};
@@ -681,26 +670,19 @@ isp_get_specific_options(device_t dev, int chan, ispsoftc_t *isp)
static int
isp_pci_attach(device_t dev)
{
- int i, locksetup = 0;
+ struct isp_pcisoftc *pcs = device_get_softc(dev);
+ ispsoftc_t *isp = &pcs->pci_isp;
+ int i;
uint32_t data, cmd, linesz, did;
- struct isp_pcisoftc *pcs;
- ispsoftc_t *isp;
size_t psize, xsize;
char fwname[32];
- pcs = device_get_softc(dev);
- if (pcs == NULL) {
- device_printf(dev, "cannot get softc\n");
- return (ENOMEM);
- }
- memset(pcs, 0, sizeof (*pcs));
-
pcs->pci_dev = dev;
- isp = &pcs->pci_isp;
isp->isp_dev = dev;
isp->isp_nchan = 1;
if (sizeof (bus_addr_t) > 4)
isp->isp_osinfo.sixtyfourbit = 1;
+ mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
/*
* Get Generic Options
@@ -980,10 +962,6 @@ isp_pci_attach(device_t dev)
goto bad;
}
- /* Make sure the lock is set up. */
- mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
- locksetup++;
-
if (isp_setup_intr(dev, pcs->irq, ISP_IFLAGS, NULL, isp_platform_intr, isp, &pcs->ih)) {
device_printf(dev, "could not setup interrupt\n");
goto bad;
@@ -1007,7 +985,7 @@ isp_pci_attach(device_t dev)
ISP_UNLOCK(isp);
if (isp_attach(isp)) {
ISP_LOCK(isp);
- isp_uninit(isp);
+ isp_shutdown(isp);
ISP_UNLOCK(isp);
goto bad;
}
@@ -1017,9 +995,6 @@ bad:
if (pcs->ih) {
(void) bus_teardown_intr(dev, pcs->irq, pcs->ih);
}
- if (locksetup) {
- mtx_destroy(&isp->isp_osinfo.lock);
- }
if (pcs->irq) {
(void) bus_release_resource(dev, SYS_RES_IRQ, pcs->iqd, pcs->irq);
}
@@ -1040,43 +1015,34 @@ bad:
free(pcs->pci_isp.isp_osinfo.pc.ptr, M_DEVBUF);
pcs->pci_isp.isp_osinfo.pc.ptr = NULL;
}
+ mtx_destroy(&isp->isp_osinfo.lock);
return (ENXIO);
}
static int
isp_pci_detach(device_t dev)
{
- struct isp_pcisoftc *pcs;
- ispsoftc_t *isp;
+ struct isp_pcisoftc *pcs = device_get_softc(dev);
+ ispsoftc_t *isp = &pcs->pci_isp;
int status;
- pcs = device_get_softc(dev);
- if (pcs == NULL) {
- return (ENXIO);
- }
- isp = (ispsoftc_t *) pcs;
status = isp_detach(isp);
if (status)
return (status);
ISP_LOCK(isp);
- isp_uninit(isp);
- if (pcs->ih) {
- (void) bus_teardown_intr(dev, pcs->irq, pcs->ih);
- }
+ isp_shutdown(isp);
ISP_UNLOCK(isp);
- mtx_destroy(&isp->isp_osinfo.lock);
+ if (pcs->ih)
+ (void) bus_teardown_intr(dev, pcs->irq, pcs->ih);
(void) bus_release_resource(dev, SYS_RES_IRQ, pcs->iqd, pcs->irq);
- if (pcs->msicount) {
+ if (pcs->msicount)
pci_release_msi(dev);
- }
(void) bus_release_resource(dev, pcs->rtp, pcs->rgd, pcs->regs);
if (pcs->regs1)
(void) bus_release_resource(dev, pcs->rtp1, pcs->rgd1, pcs->regs1);
if (pcs->regs2)
(void) bus_release_resource(dev, pcs->rtp2, pcs->rgd2, pcs->regs2);
- /*
- * XXX: THERE IS A LOT OF LEAKAGE HERE
- */
+ isp_pci_mbxdmafree(isp);
if (pcs->pci_isp.isp_param) {
free(pcs->pci_isp.isp_param, M_DEVBUF);
pcs->pci_isp.isp_param = NULL;
@@ -1085,6 +1051,7 @@ isp_pci_detach(device_t dev)
free(pcs->pci_isp.isp_osinfo.pc.ptr, M_DEVBUF);
pcs->pci_isp.isp_osinfo.pc.ptr = NULL;
}
+ mtx_destroy(&isp->isp_osinfo.lock);
return (0);
}
@@ -1571,56 +1538,39 @@ isp_pci_mbxdma(ispsoftc_t *isp)
struct imush im;
isp_ecmd_t *ecmd;
- /*
- * Already been here? If so, leave...
- */
- if (isp->isp_rquest) {
+ /* Already been here? If so, leave... */
+ if (isp->isp_xflist != NULL)
+ return (0);
+ if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0)
return (0);
- }
ISP_UNLOCK(isp);
-
- if (isp->isp_maxcmds == 0) {
- isp_prt(isp, ISP_LOGERR, "maxcmds not set");
- ISP_LOCK(isp);
- return (1);
- }
+ if (isp->isp_rquest != NULL)
+ goto gotmaxcmds;
hlim = BUS_SPACE_MAXADDR;
if (IS_ULTRA2(isp) || IS_FC(isp) || IS_1240(isp)) {
- if (sizeof (bus_size_t) > 4) {
+ if (sizeof (bus_size_t) > 4)
slim = (bus_size_t) (1ULL << 32);
- } else {
+ else
slim = (bus_size_t) (1UL << 31);
- }
llim = BUS_SPACE_MAXADDR;
} else {
- llim = BUS_SPACE_MAXADDR_32BIT;
slim = (1UL << 24);
+ llim = BUS_SPACE_MAXADDR_32BIT;
}
-
- len = isp->isp_maxcmds * sizeof (struct isp_pcmd);
- isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
-
- if (isp->isp_osinfo.sixtyfourbit) {
+ if (isp->isp_osinfo.sixtyfourbit)
nsegs = ISP_NSEG64_MAX;
- } else {
+ else
nsegs = ISP_NSEG_MAX;
- }
- if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_PCD(isp)), 1, slim, llim, hlim, NULL, NULL, BUS_SPACE_MAXSIZE, nsegs, slim, 0, &isp->isp_osinfo.dmat)) {
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
+ if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_PCD(isp)), 1,
+ slim, llim, hlim, NULL, NULL, BUS_SPACE_MAXSIZE, nsegs, slim, 0,
+ &isp->isp_osinfo.dmat)) {
ISP_LOCK(isp);
isp_prt(isp, ISP_LOGERR, "could not create master dma tag");
return (1);
}
- len = sizeof (isp_hdl_t) * isp->isp_maxcmds;
- isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
- for (len = 0; len < isp->isp_maxcmds - 1; len++) {
- isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
- }
- isp->isp_xffree = isp->isp_xflist;
-
/*
* Allocate and map the request queue and a region for external
* DMA addressable command/status structures (22XX and later).
@@ -1632,20 +1582,20 @@ isp_pci_mbxdma(ispsoftc_t *isp)
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
len, 1, len, 0, &isp->isp_osinfo.reqdmat)) {
isp_prt(isp, ISP_LOGERR, "cannot create request DMA tag");
- goto bad1;
+ goto bad;
}
if (bus_dmamem_alloc(isp->isp_osinfo.reqdmat, (void **)&base,
BUS_DMA_COHERENT, &isp->isp_osinfo.reqmap) != 0) {
isp_prt(isp, ISP_LOGERR, "cannot allocate request DMA memory");
bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
- goto bad1;
+ goto bad;
}
isp->isp_rquest = base;
im.error = 0;
if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap,
base, len, imc, &im, 0) || im.error) {
isp_prt(isp, ISP_LOGERR, "error loading request DMA map %d", im.error);
- goto bad1;
+ goto bad;
}
isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx",
(uintmax_t)im.maddr, (uintmax_t)len);
@@ -1673,20 +1623,20 @@ isp_pci_mbxdma(ispsoftc_t *isp)
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
len, 1, len, 0, &isp->isp_osinfo.respdmat)) {
isp_prt(isp, ISP_LOGERR, "cannot create response DMA tag");
- goto bad1;
+ goto bad;
}
if (bus_dmamem_alloc(isp->isp_osinfo.respdmat, (void **)&base,
BUS_DMA_COHERENT, &isp->isp_osinfo.respmap) != 0) {
isp_prt(isp, ISP_LOGERR, "cannot allocate response DMA memory");
bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
- goto bad1;
+ goto bad;
}
isp->isp_result = base;
im.error = 0;
if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap,
base, len, imc, &im, 0) || im.error) {
isp_prt(isp, ISP_LOGERR, "error loading response DMA map %d", im.error);
- goto bad1;
+ goto bad;
}
isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx",
(uintmax_t)im.maddr, (uintmax_t)len);
@@ -1702,13 +1652,13 @@ isp_pci_mbxdma(ispsoftc_t *isp)
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
len, 1, len, 0, &isp->isp_osinfo.atiodmat)) {
isp_prt(isp, ISP_LOGERR, "cannot create ATIO DMA tag");
- goto bad1;
+ goto bad;
}
if (bus_dmamem_alloc(isp->isp_osinfo.atiodmat, (void **)&base,
BUS_DMA_COHERENT, &isp->isp_osinfo.atiomap) != 0) {
isp_prt(isp, ISP_LOGERR, "cannot allocate ATIO DMA memory");
bus_dma_tag_destroy(isp->isp_osinfo.atiodmat);
- goto bad1;
+ goto bad;
}
isp->isp_atioq = base;
im.error = 0;
@@ -1754,6 +1704,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
base, ISP_FC_SCRLEN, imc, &im, 0) || im.error) {
bus_dmamem_free(isp->isp_osinfo.scdmat,
base, fc->scmap);
+ FCPARAM(isp, cmap)->isp_scratch = NULL;
goto bad;
}
FCPARAM(isp, cmap)->isp_scdma = im.maddr;
@@ -1775,83 +1726,134 @@ isp_pci_mbxdma(ispsoftc_t *isp)
}
}
+ if (isp->isp_maxcmds == 0) {
+ ISP_LOCK(isp);
+ return (0);
+ }
+
+gotmaxcmds:
+ len = isp->isp_maxcmds * sizeof (struct isp_pcmd);
+ isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *)
+ malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
for (i = 0; i < isp->isp_maxcmds; i++) {
struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i];
error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap);
if (error) {
isp_prt(isp, ISP_LOGERR, "error %d creating per-cmd DMA maps", error);
while (--i >= 0) {
- bus_dmamap_destroy(isp->isp_osinfo.dmat, isp->isp_osinfo.pcmd_pool[i].dmap);
+ bus_dmamap_destroy(isp->isp_osinfo.dmat,
+ isp->isp_osinfo.pcmd_pool[i].dmap);
}
goto bad;
}
callout_init_mtx(&pcmd->wdog, &isp->isp_osinfo.lock, 0);
- if (i == isp->isp_maxcmds-1) {
+ if (i == isp->isp_maxcmds-1)
pcmd->next = NULL;
- } else {
+ else
pcmd->next = &isp->isp_osinfo.pcmd_pool[i+1];
- }
}
isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0];
+
+ len = sizeof (isp_hdl_t) * isp->isp_maxcmds;
+ isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ for (len = 0; len < isp->isp_maxcmds - 1; len++)
+ isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
+ isp->isp_xffree = isp->isp_xflist;
+
ISP_LOCK(isp);
return (0);
bad:
+ isp_pci_mbxdmafree(isp);
+ ISP_LOCK(isp);
+ return (1);
+}
+
+static void
+isp_pci_mbxdmafree(ispsoftc_t *isp)
+{
+ int i;
+
+ if (isp->isp_xflist != NULL) {
+ free(isp->isp_xflist, M_DEVBUF);
+ isp->isp_xflist = NULL;
+ }
+ if (isp->isp_osinfo.pcmd_pool != NULL) {
+ for (i = 0; i < isp->isp_maxcmds; i++) {
+ bus_dmamap_destroy(isp->isp_osinfo.dmat,
+ isp->isp_osinfo.pcmd_pool[i].dmap);
+ }
+ free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
+ isp->isp_osinfo.pcmd_pool = NULL;
+ }
if (IS_FC(isp)) {
- while (--cmap >= 0) {
- struct isp_fc *fc = ISP_FC_PC(isp, cmap);
- bus_dmamap_unload(isp->isp_osinfo.scdmat, fc->scmap);
- bus_dmamem_free(isp->isp_osinfo.scdmat,
- FCPARAM(isp, cmap)->isp_scratch, fc->scmap);
+ for (i = 0; i < isp->isp_nchan; i++) {
+ struct isp_fc *fc = ISP_FC_PC(isp, i);
+ if (FCPARAM(isp, i)->isp_scdma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.scdmat,
+ fc->scmap);
+ FCPARAM(isp, i)->isp_scdma = 0;
+ }
+ if (FCPARAM(isp, i)->isp_scratch != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.scdmat,
+ FCPARAM(isp, i)->isp_scratch, fc->scmap);
+ FCPARAM(isp, i)->isp_scratch = NULL;
+ }
while (fc->nexus_free_list) {
struct isp_nexus *n = fc->nexus_free_list;
fc->nexus_free_list = n->next;
free(n, M_DEVBUF);
}
}
- bus_dma_tag_destroy(isp->isp_osinfo.scdmat);
- bus_dmamap_unload(isp->isp_osinfo.iocbdmat, isp->isp_osinfo.iocbmap);
- bus_dmamem_free(isp->isp_osinfo.iocbdmat, isp->isp_iocb,
- isp->isp_osinfo.iocbmap);
- bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat);
- }
-bad1:
- if (isp->isp_rquest_dma != 0) {
- bus_dmamap_unload(isp->isp_osinfo.reqdmat,
- isp->isp_osinfo.reqmap);
- }
- if (isp->isp_rquest != NULL) {
- bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
- isp->isp_osinfo.reqmap);
- bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
- }
- if (isp->isp_result_dma != 0) {
- bus_dmamap_unload(isp->isp_osinfo.respdmat,
- isp->isp_osinfo.respmap);
- }
- if (isp->isp_result != NULL) {
- bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result,
- isp->isp_osinfo.respmap);
- bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ if (isp->isp_iocb_dma != 0) {
+ bus_dma_tag_destroy(isp->isp_osinfo.scdmat);
+ bus_dmamap_unload(isp->isp_osinfo.iocbdmat,
+ isp->isp_osinfo.iocbmap);
+ isp->isp_iocb_dma = 0;
+ }
+ if (isp->isp_iocb != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.iocbdmat,
+ isp->isp_iocb, isp->isp_osinfo.iocbmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.iocbdmat);
+ }
}
#ifdef ISP_TARGET_MODE
if (IS_24XX(isp)) {
if (isp->isp_atioq_dma != 0) {
bus_dmamap_unload(isp->isp_osinfo.atiodmat,
isp->isp_osinfo.atiomap);
+ isp->isp_atioq_dma = 0;
}
if (isp->isp_atioq != NULL) {
- bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_atioq,
+ bus_dmamem_free(isp->isp_osinfo.atiodmat, isp->isp_atioq,
isp->isp_osinfo.atiomap);
bus_dma_tag_destroy(isp->isp_osinfo.atiodmat);
+ isp->isp_atioq = NULL;
}
}
#endif
- free(isp->isp_xflist, M_DEVBUF);
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- isp->isp_rquest = NULL;
- ISP_LOCK(isp);
- return (1);
+ if (isp->isp_result_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.respdmat,
+ isp->isp_osinfo.respmap);
+ isp->isp_result_dma = 0;
+ }
+ if (isp->isp_result != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result,
+ isp->isp_osinfo.respmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ isp->isp_result = NULL;
+ }
+ if (isp->isp_rquest_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.reqdmat,
+ isp->isp_osinfo.reqmap);
+ isp->isp_rquest_dma = 0;
+ }
+ if (isp->isp_rquest != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
+ isp->isp_osinfo.reqmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ isp->isp_rquest = NULL;
+ }
}
typedef struct {
@@ -2071,21 +2073,11 @@ isp_pci_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff)
return (CMD_QUEUED);
}
-static void
-isp_pci_reset0(ispsoftc_t *isp)
+static int
+isp_pci_irqsetup(ispsoftc_t *isp)
{
- ISP_DISABLE_INTS(isp);
-}
-static void
-isp_pci_reset1(ispsoftc_t *isp)
-{
- if (!IS_24XX(isp)) {
- /* Make sure the BIOS is disabled */
- isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
- }
- /* and enable interrupts */
- ISP_ENABLE_INTS(isp);
+ return (0);
}
static void
diff --git a/sys/dev/isp/isp_sbus.c b/sys/dev/isp/isp_sbus.c
index b3963b9905e56..65c5ee52da1f8 100644
--- a/sys/dev/isp/isp_sbus.c
+++ b/sys/dev/isp/isp_sbus.c
@@ -55,11 +55,8 @@ static uint32_t isp_sbus_rd_reg(ispsoftc_t *, int);
static void isp_sbus_wr_reg(ispsoftc_t *, int, uint32_t);
static int isp_sbus_rd_isr(ispsoftc_t *, uint16_t *, uint16_t *, uint16_t *);
static int isp_sbus_mbxdma(ispsoftc_t *);
+static void isp_sbus_mbxdmafree(ispsoftc_t *);
static int isp_sbus_dmasetup(ispsoftc_t *, XS_T *, void *);
-
-
-static void isp_sbus_reset0(ispsoftc_t *);
-static void isp_sbus_reset1(ispsoftc_t *);
static void isp_sbus_dumpregs(ispsoftc_t *, const char *);
static struct ispmdvec mdvec = {
@@ -69,8 +66,7 @@ static struct ispmdvec mdvec = {
isp_sbus_mbxdma,
isp_sbus_dmasetup,
isp_common_dmateardown,
- isp_sbus_reset0,
- isp_sbus_reset1,
+ NULL,
isp_sbus_dumpregs,
NULL,
BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
@@ -140,20 +136,15 @@ isp_sbus_probe(device_t dev)
static int
isp_sbus_attach(device_t dev)
{
+ struct isp_sbussoftc *sbs = device_get_softc(dev);
+ ispsoftc_t *isp = &sbs->sbus_isp;
int tval, isp_debug, role, ispburst, default_id;
- struct isp_sbussoftc *sbs;
- ispsoftc_t *isp = NULL;
- int locksetup = 0;
int ints_setup = 0;
- sbs = device_get_softc(dev);
- if (sbs == NULL) {
- device_printf(dev, "cannot get softc\n");
- return (ENOMEM);
- }
-
sbs->sbus_dev = dev;
sbs->sbus_mdvec = mdvec;
+ isp->isp_dev = dev;
+ mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
role = 0;
if (resource_int_value(device_get_name(dev), device_get_unit(dev),
@@ -179,7 +170,6 @@ isp_sbus_attach(device_t dev)
sbs->sbus_poff[SXP_BLOCK >> _BLK_REG_SHFT] = SBUS_SXP_REGS_OFF;
sbs->sbus_poff[RISC_BLOCK >> _BLK_REG_SHFT] = SBUS_RISC_REGS_OFF;
sbs->sbus_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
- isp = &sbs->sbus_isp;
isp->isp_regs = sbs->regs;
isp->isp_mdvec = &sbs->sbus_mdvec;
isp->isp_bustype = ISP_BT_SBUS;
@@ -187,7 +177,6 @@ isp_sbus_attach(device_t dev)
isp->isp_param = &sbs->sbus_param;
isp->isp_osinfo.pc.ptr = &sbs->sbus_spi;
isp->isp_revision = 0; /* XXX */
- isp->isp_dev = dev;
isp->isp_nchan = 1;
if (IS_FC(isp))
ISP_FC_PC(isp, 0)->def_role = role;
@@ -266,10 +255,6 @@ isp_sbus_attach(device_t dev)
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
"debug", &isp_debug);
- /* Make sure the lock is set up. */
- mtx_init(&isp->isp_osinfo.lock, "isp", NULL, MTX_DEF);
- locksetup++;
-
sbs->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sbs->iqd,
RF_ACTIVE | RF_SHAREABLE);
if (sbs->irq == NULL) {
@@ -301,14 +286,13 @@ isp_sbus_attach(device_t dev)
*/
ISP_LOCK(isp);
if (isp_reinit(isp, 1) != 0) {
- isp_uninit(isp);
ISP_UNLOCK(isp);
goto bad;
}
ISP_UNLOCK(isp);
if (isp_attach(isp)) {
ISP_LOCK(isp);
- isp_uninit(isp);
+ isp_shutdown(isp);
ISP_UNLOCK(isp);
goto bad;
}
@@ -324,41 +308,33 @@ bad:
bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq);
}
- if (locksetup && isp) {
- mtx_destroy(&isp->isp_osinfo.lock);
- }
-
if (sbs->regs) {
(void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd,
sbs->regs);
}
+ mtx_destroy(&isp->isp_osinfo.lock);
return (ENXIO);
}
static int
isp_sbus_detach(device_t dev)
{
- struct isp_sbussoftc *sbs;
- ispsoftc_t *isp;
+ struct isp_sbussoftc *sbs = device_get_softc(dev);
+ ispsoftc_t *isp = &sbs->sbus_isp;
int status;
- sbs = device_get_softc(dev);
- if (sbs == NULL) {
- return (ENXIO);
- }
- isp = (ispsoftc_t *) sbs;
status = isp_detach(isp);
if (status)
return (status);
ISP_LOCK(isp);
- isp_uninit(isp);
- if (sbs->ih) {
- (void) bus_teardown_intr(dev, sbs->irq, sbs->ih);
- }
+ isp_shutdown(isp);
ISP_UNLOCK(isp);
- mtx_destroy(&isp->isp_osinfo.lock);
+ if (sbs->ih)
+ (void) bus_teardown_intr(dev, sbs->irq, sbs->ih);
(void) bus_release_resource(dev, SYS_RES_IRQ, sbs->iqd, sbs->irq);
(void) bus_release_resource(dev, SYS_RES_MEMORY, sbs->rgd, sbs->regs);
+ isp_sbus_mbxdmafree(isp);
+ mtx_destroy(&isp->isp_osinfo.lock);
return (0);
}
@@ -436,25 +412,14 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
int i, error;
struct imush im;
- /*
- * Already been here? If so, leave...
- */
- if (isp->isp_rquest) {
+ /* Already been here? If so, leave... */
+ if (isp->isp_xflist != NULL)
+ return (0);
+ if (isp->isp_rquest != NULL && isp->isp_maxcmds == 0)
return (0);
- }
-
ISP_UNLOCK(isp);
-
- len = sizeof (struct isp_pcmd) * isp->isp_maxcmds;
- isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *)
- malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
- len = sizeof (isp_hdl_t *) * isp->isp_maxcmds;
- isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
- for (len = 0; len < isp->isp_maxcmds - 1; len++) {
- isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
- }
- isp->isp_xffree = isp->isp_xflist;
- len = sizeof (bus_dmamap_t) * isp->isp_maxcmds;
+ if (isp->isp_rquest != NULL)
+ goto gotmaxcmds;
if (isp_dma_tag_create(BUS_DMA_ROOTARG(ISP_SBD(isp)), 1,
BUS_SPACE_MAXADDR_24BIT+1, BUS_SPACE_MAXADDR_32BIT,
@@ -480,6 +445,7 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
goto bad;
}
+ isp->isp_rquest = base;
im.error = 0;
if (bus_dmamap_load(isp->isp_osinfo.reqdmat, isp->isp_osinfo.reqmap,
base, len, imc, &im, 0) || im.error) {
@@ -488,7 +454,6 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
}
isp_prt(isp, ISP_LOGDEBUG0, "request area @ 0x%jx/0x%jx",
(uintmax_t)im.maddr, (uintmax_t)len);
- isp->isp_rquest = base;
isp->isp_rquest_dma = im.maddr;
/*
@@ -507,6 +472,7 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
goto bad;
}
+ isp->isp_result = base;
im.error = 0;
if (bus_dmamap_load(isp->isp_osinfo.respdmat, isp->isp_osinfo.respmap,
base, len, imc, &im, 0) || im.error) {
@@ -515,9 +481,17 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
}
isp_prt(isp, ISP_LOGDEBUG0, "response area @ 0x%jx/0x%jx",
(uintmax_t)im.maddr, (uintmax_t)len);
- isp->isp_result = base;
isp->isp_result_dma = im.maddr;
+ if (isp->isp_maxcmds == 0) {
+ ISP_LOCK(isp);
+ return (0);
+ }
+
+gotmaxcmds:
+ len = sizeof (struct isp_pcmd) * isp->isp_maxcmds;
+ isp->isp_osinfo.pcmd_pool = (struct isp_pcmd *)
+ malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
for (i = 0; i < isp->isp_maxcmds; i++) {
struct isp_pcmd *pcmd = &isp->isp_osinfo.pcmd_pool[i];
error = bus_dmamap_create(isp->isp_osinfo.dmat, 0, &pcmd->dmap);
@@ -538,33 +512,61 @@ isp_sbus_mbxdma(ispsoftc_t *isp)
}
}
isp->isp_osinfo.pcmd_free = &isp->isp_osinfo.pcmd_pool[0];
+
+ len = sizeof (isp_hdl_t *) * isp->isp_maxcmds;
+ isp->isp_xflist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
+ for (len = 0; len < isp->isp_maxcmds - 1; len++)
+ isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
+ isp->isp_xffree = isp->isp_xflist;
+
ISP_LOCK(isp);
return (0);
bad:
- if (isp->isp_rquest_dma != 0) {
- bus_dmamap_unload(isp->isp_osinfo.reqdmat,
- isp->isp_osinfo.reqmap);
+ isp_sbus_mbxdmafree(isp);
+ ISP_LOCK(isp);
+ return (1);
+}
+
+static void
+isp_sbus_mbxdmafree(ispsoftc_t *isp)
+{
+ int i;
+
+ if (isp->isp_xflist != NULL) {
+ free(isp->isp_xflist, M_DEVBUF);
+ isp->isp_xflist = NULL;
}
- if (isp->isp_rquest != NULL) {
- bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
- isp->isp_osinfo.reqmap);
- bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ if (isp->isp_osinfo.pcmd_pool != NULL) {
+ for (i = 0; i < isp->isp_maxcmds; i++) {
+ bus_dmamap_destroy(isp->isp_osinfo.dmat,
+ isp->isp_osinfo.pcmd_pool[i].dmap);
+ }
+ free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
+ isp->isp_osinfo.pcmd_pool = NULL;
}
if (isp->isp_result_dma != 0) {
bus_dmamap_unload(isp->isp_osinfo.respdmat,
isp->isp_osinfo.respmap);
+ isp->isp_result_dma = 0;
}
if (isp->isp_result != NULL) {
bus_dmamem_free(isp->isp_osinfo.respdmat, isp->isp_result,
isp->isp_osinfo.respmap);
bus_dma_tag_destroy(isp->isp_osinfo.respdmat);
+ isp->isp_result = NULL;
+ }
+ if (isp->isp_rquest_dma != 0) {
+ bus_dmamap_unload(isp->isp_osinfo.reqdmat,
+ isp->isp_osinfo.reqmap);
+ isp->isp_rquest_dma = 0;
+ }
+ if (isp->isp_rquest != NULL) {
+ bus_dmamem_free(isp->isp_osinfo.reqdmat, isp->isp_rquest,
+ isp->isp_osinfo.reqmap);
+ bus_dma_tag_destroy(isp->isp_osinfo.reqdmat);
+ isp->isp_rquest = NULL;
}
- free(isp->isp_xflist, M_DEVBUF);
- free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
- isp->isp_rquest = NULL;
- ISP_LOCK(isp);
- return (1);
}
typedef struct {
@@ -663,18 +665,6 @@ isp_sbus_dmasetup(ispsoftc_t *isp, struct ccb_scsiio *csio, void *ff)
}
static void
-isp_sbus_reset0(ispsoftc_t *isp)
-{
- ISP_DISABLE_INTS(isp);
-}
-
-static void
-isp_sbus_reset1(ispsoftc_t *isp)
-{
- ISP_ENABLE_INTS(isp);
-}
-
-static void
isp_sbus_dumpregs(ispsoftc_t *isp, const char *msg)
{
if (msg)
diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h
index caaba74561765..72193d6c4b729 100644
--- a/sys/dev/isp/ispvar.h
+++ b/sys/dev/isp/ispvar.h
@@ -64,8 +64,7 @@ struct ispmdvec {
int (*dv_mbxdma) (ispsoftc_t *);
int (*dv_dmaset) (ispsoftc_t *, XS_T *, void *);
void (*dv_dmaclr) (ispsoftc_t *, XS_T *, uint32_t);
- void (*dv_reset0) (ispsoftc_t *);
- void (*dv_reset1) (ispsoftc_t *);
+ int (*dv_irqsetup) (ispsoftc_t *);
void (*dv_dregs) (ispsoftc_t *, const char *);
const void * dv_ispfw; /* ptr to f/w */
uint16_t dv_conf1;
@@ -105,10 +104,8 @@ struct ispmdvec {
if ((isp)->isp_mdvec->dv_dmaclr) \
(*(isp)->isp_mdvec->dv_dmaclr)((isp), (xs), (hndl))
-#define ISP_RESET0(isp) \
- if ((isp)->isp_mdvec->dv_reset0) (*(isp)->isp_mdvec->dv_reset0)((isp))
-#define ISP_RESET1(isp) \
- if ((isp)->isp_mdvec->dv_reset1) (*(isp)->isp_mdvec->dv_reset1)((isp))
+#define ISP_IRQSETUP(isp) \
+ (((isp)->isp_mdvec->dv_irqsetup) ? (*(isp)->isp_mdvec->dv_irqsetup)(isp) : 0)
#define ISP_DUMPREGS(isp, m) \
if ((isp)->isp_mdvec->dv_dregs) (*(isp)->isp_mdvec->dv_dregs)((isp),(m))
@@ -565,13 +562,9 @@ struct ispsoftc {
* Volatile state
*/
- volatile uint32_t : 8,
- : 2,
- isp_dead : 1,
- : 1,
- isp_mboxbsy : 1, /* mailbox command active */
- isp_state : 3,
- isp_nactive : 16; /* how many commands active */
+ volatile u_int isp_mboxbsy; /* mailbox command active */
+ volatile u_int isp_state;
+ volatile u_int isp_nactive; /* how many commands active */
volatile mbreg_t isp_curmbx; /* currently active mailbox command */
volatile uint32_t isp_reqodx; /* index of last ISP pickup */
volatile uint32_t isp_reqidx; /* index of next request */
@@ -819,6 +812,11 @@ void isp_init(ispsoftc_t *);
int isp_reinit(ispsoftc_t *, int);
/*
+ * Shutdown hardware after use.
+ */
+void isp_shutdown(ispsoftc_t *);
+
+/*
* Internal Interrupt Service Routine
*
* The outer layers do the spade work to get the appropriate status register,