|
From: <swg...@us...> - 2008-04-24 06:34:11
|
Revision: 355
http://scst.svn.sourceforge.net/scst/?rev=355&view=rev
Author: swgruszka
Date: 2008-04-23 23:34:08 -0700 (Wed, 23 Apr 2008)
Log Message:
-----------
Synchronize with Feral CVS repository:
- use kthread
- MBOX_ACQUIRE macro redefined
Modified Paths:
--------------
trunk/qla_isp/common/isp.c
trunk/qla_isp/common/isp_tpublic.h
trunk/qla_isp/linux/isp_cb_ops.c
trunk/qla_isp/linux/isp_linux.c
trunk/qla_isp/linux/isp_linux.h
trunk/qla_isp/linux/isp_pci.c
trunk/qla_isp/linux/isp_scst.c
trunk/qla_isp/linux/scsi_target.c
Modified: trunk/qla_isp/common/isp.c
===================================================================
--- trunk/qla_isp/common/isp.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/common/isp.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp.c,v 1.203 2008/03/16 00:34:49 mjacob Exp $ */
+/* $Id: isp.c,v 1.204 2008/04/15 22:40:52 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -5406,13 +5406,14 @@
uint8_t ts = completion_status & 0xff;
/*
* Only whine if this isn't the expected fallout of
- * aborting the command.
+ * aborting the command or resetting the target.
*/
if (etype != RQSTYPE_RESPONSE) {
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (type 0x%x)",
sp->req_handle, etype);
} else if (ts != RQCS_ABORTED &&
+ ts != RQCS_RESET_OCCURRED &&
sp->req_handle != ISP_SPCL_HANDLE) {
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (status 0x%x)",
Modified: trunk/qla_isp/common/isp_tpublic.h
===================================================================
--- trunk/qla_isp/common/isp_tpublic.h 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/common/isp_tpublic.h 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp_tpublic.h,v 1.42 2008/02/27 21:00:26 mjacob Exp $ */
+/* $Id: isp_tpublic.h,v 1.43 2008/04/15 22:40:52 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -114,7 +114,7 @@
*
* The r_version tag defines the version of this API.
*/
-#define QR_VERSION 19
+#define QR_VERSION 20
typedef struct {
/* NB: structure tags from here to r_version must never change */
void * r_identity;
@@ -190,6 +190,7 @@
uint64_t nt_tagval; /* tag value */
uint32_t nt_channel; /* channel id */
tmd_ncode_t nt_ncode; /* action */
+ void * nt_tmd; /* TMD for this notify */
void * nt_lreserved;
void * nt_hreserved;
} tmd_notify_t;
Modified: trunk/qla_isp/linux/isp_cb_ops.c
===================================================================
--- trunk/qla_isp/linux/isp_cb_ops.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/isp_cb_ops.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp_cb_ops.c,v 1.88 2008/03/15 18:16:47 mjacob Exp $ */
+/* $Id: isp_cb_ops.c,v 1.89 2008/04/15 22:41:03 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -159,7 +159,7 @@
} else if (strncmp(buf, "rescan", 6) == 0) {
if (IS_FC(isp)) {
for (io = 0; io < isp->isp_nchan; io++) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __FUNCTION__, __LINE__);
}
io = len;
}
@@ -482,7 +482,7 @@
if (IS_FC(isp)) {
for (i = 0; i < isp->isp_nchan; i++) {
FCPARAM(isp, i)->isp_loopstate = LOOP_PDB_RCVD;
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__);
}
}
break;
Modified: trunk/qla_isp/linux/isp_linux.c
===================================================================
--- trunk/qla_isp/linux/isp_linux.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/isp_linux.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp_linux.c,v 1.229 2008/03/15 18:16:47 mjacob Exp $ */
+/* $Id: isp_linux.c,v 1.230 2008/04/15 22:41:03 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -313,7 +313,7 @@
*/
if (IS_FC(isp)) {
if (result == CMD_RQLATER && ISP_DATA(isp, XS_CHANNEL(f))->deadloop == 0) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, chan), 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, chan), 0, __FUNCTION__, __LINE__);
}
}
@@ -485,7 +485,7 @@
*/
isplinux_append_to_waitq(isp, Cmnd);
if (IS_FC(isp) && ISP_DATA(isp, XS_CHANNEL(Cmnd))->deadloop == 0) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, XS_CHANNEL(Cmnd)), 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, XS_CHANNEL(Cmnd)), 0, __FUNCTION__, __LINE__);
}
result = 0;
} else if (result == CMD_COMPLETE) {
@@ -1190,19 +1190,21 @@
{
info_t *ip = arg;
isp = ip->i_identity;
- if (ip->i_type == I_FC) {
+ if (ip->i_channel >= isp->isp_nchan) {
+ ip->i_error = -ENODEV;
+ } else if (IS_FC(isp)) {
fcparam *fcp = FCPARAM(isp, ip->i_channel);
+ ip->i_type = I_FC;
ip->i_id.fc.wwnn_nvram = fcp->isp_wwnn_nvram;
ip->i_id.fc.wwpn_nvram = fcp->isp_wwpn_nvram;
ip->i_id.fc.wwnn = fcp->isp_wwnn;
ip->i_id.fc.wwpn = fcp->isp_wwpn;
ip->i_error = 0;
- } else if (ip->i_type == I_SPI) {
+ } else {
sdparam *sdp = SDPARAM(isp, ip->i_channel);
+ ip->i_type = I_SPI;
ip->i_id.spi.iid = sdp->isp_initiator_id;
ip->i_error = 0;
- } else {
- ip->i_error = -EINVAL;
}
break;
}
@@ -1297,7 +1299,7 @@
isp_prt(isp, ISP_LOGTDEBUG1, "freeing tmd %p [%llx]", tmd, tmd->cd_tagval);
if (tmd->cd_lflags & CDFL_RESRC_FILL) {
if (isp_target_putback_atio(isp, tmd)) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__);
ISP_UNLK_SOFTC(isp);
break;
}
@@ -1933,7 +1935,7 @@
isp_endcmd(isp, aep, SCSI_BUSY, 0);
if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) {
isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port");
- ISP_THREAD_EVENT(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
}
return;
}
@@ -2024,7 +2026,7 @@
isp_endcmd(isp, aep, SCSI_BUSY, 0);
if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) {
isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port");
- ISP_THREAD_EVENT(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
}
return;
}
@@ -2119,7 +2121,7 @@
} else {
tmd->cd_portid = PORT_NONE;
isp_add_wwn_entry(isp, 0, tmd->cd_iid, tmd->cd_nphdl, PORT_NONE);
- (void) ISP_THREAD_EVENT(isp, ISP_THREAD_FINDPORTID, tmd, 0, __FUNCTION__, __LINE__);
+ (void) isp_thread_event(isp, ISP_THREAD_FINDPORTID, tmd, 0, __FUNCTION__, __LINE__);
}
}
}
@@ -2219,7 +2221,7 @@
isp_endcmd(isp, aep, chan, SCSI_BUSY, 0);
if (jiffies - isp->isp_osinfo.out_of_tmds > 30 * HZ) {
isp_prt(isp, ISP_LOGERR, "out of TMDs too long: disabling port");
- ISP_THREAD_EVENT(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
}
return;
}
@@ -2316,7 +2318,7 @@
CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
} else {
isp_prt(isp, ISP_LOGTDEBUG0, "[0x%llx] asking taskthread to find iid of initiator", (unsigned long long) tmd->cd_tagval);
- if (ISP_THREAD_EVENT(isp, ISP_THREAD_FINDIID, tmd, 0, __FUNCTION__, __LINE__)) {
+ if (isp_thread_event(isp, ISP_THREAD_FINDIID, tmd, 0, __FUNCTION__, __LINE__)) {
isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
MEMZERO(tmd, TMD_SIZE);
if (isp->isp_osinfo.tfreelist) {
@@ -2487,7 +2489,7 @@
continue;
}
}
- ISP_THREAD_EVENT(isp, ISP_THREAD_LOGOUT, &FCPARAM(isp, tmd->cd_channel)->portdb[i], 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_LOGOUT, &FCPARAM(isp, tmd->cd_channel)->portdb[i], 0, __FUNCTION__, __LINE__);
break;
}
}
@@ -3119,7 +3121,7 @@
tgt = lp->ini_map_idx - 1;
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived at", tgt, lp->node_wwn, lp->port_wwn);
arg = tgt | (bus << 16);
- ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
} else {
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "arrived", lp->node_wwn, lp->port_wwn);
}
@@ -3167,7 +3169,7 @@
lp->ini_map_idx = 0;
isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", tgt, lp->node_wwn, lp->port_wwn);
arg = tgt | (bus << 16) | (1 << 31);
- ISP_THREAD_EVENT(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_SCSI_SCAN, (void *)arg, 0, __FUNCTION__, __LINE__);
} else if (lp->reserved == 0) {
isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, isp_class3_roles[lp->roles], "departed", lp->node_wwn, lp->port_wwn);
}
@@ -3201,7 +3203,7 @@
isp_prt(isp, ISP_LOGINFO, "Chan %d Other Change Notify occurred", bus);
}
if (isp->isp_state >= ISP_INITSTATE) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__);
}
break;
}
@@ -3411,6 +3413,7 @@
ins->notify.nt_ncode = NT_ABORT_TASK;
ins->notify.nt_need_ack = 1;
ins->notify.nt_channel = chan;
+ ins->notify.nt_tmd = NULL;
/*
* Find the command if possible and mark it aborted and needing cleanup
*/
@@ -3420,6 +3423,7 @@
if (ins->notify.nt_tagval == tmd->cd_tagval && ins->notify.nt_channel == tmd->cd_channel) {
isp_prt(isp, ISP_LOGTINFO, "[0x%llx] marked as aborted", (unsigned long long) tmd->cd_tagval);
tmd->cd_lflags |= CDFL_ABORTED|CDFL_NEED_CLNUP;
+ ins->notify.nt_tmd = tmd;
break;
}
}
@@ -3717,7 +3721,7 @@
ISP_DATA(isp, mbox6)->blocked = 1;
ISP_RESET0(isp);
isp_shutdown(isp);
- ISP_THREAD_EVENT(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_REINIT, NULL, 0, __FUNCTION__, __LINE__);
break;
}
case ISPASYNC_FW_RESTARTED:
@@ -3725,7 +3729,7 @@
if (IS_FC(isp)) {
int i;
for (i = 0; i < isp->isp_nchan; i++) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 0, __FUNCTION__, __LINE__);
}
}
break;
@@ -3913,7 +3917,7 @@
fcparam *fcp = FCPARAM(isp, i);
if (fcp->role != ISP_ROLE_NONE && ISP_DATA(isp, i)->fcrswdog && ISP_DATA(isp, i)->deadloop == 0) {
ISP_DATA(isp, i)->fcrswdog = 1;
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FC_RESCAN, fcp, 0, __FUNCTION__, __LINE__);
}
}
}
@@ -3931,9 +3935,9 @@
isp->isp_osinfo.waiting_t = wt->cd_next;
wt->cd_next = NULL;
if (wt->cd_lastoff == 0) {
- ISP_THREAD_EVENT(isp, ISP_THREAD_FINDIID, wt, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_FINDIID, wt, 0, __FUNCTION__, __LINE__);
} else {
- ISP_THREAD_EVENT(isp, ISP_THREAD_RESTART_AT7, wt, 0, __FUNCTION__, __LINE__);
+ isp_thread_event(isp, ISP_THREAD_RESTART_AT7, wt, 0, __FUNCTION__, __LINE__);
}
}
}
@@ -4172,7 +4176,7 @@
int
isplinux_common_init(ispsoftc_t *isp)
{
- int retval, chan;
+ int retval, chan, i;
unsigned long flags;
if (isp_nofwreload & (1 << isp->isp_unit)) {
@@ -4250,8 +4254,18 @@
ISP_TLOCK_INIT(isp);
sema_init(&isp->mbox_sem, 1);
sema_init(&isp->mbox_c_sem, 0);
- sema_init(&isp->fcs_sem, 1);
+ init_waitqueue_head(&isp->isp_osinfo.trq);
+ for (i = 0; i < MAX_THREAD_ACTION; i++) {
+ init_waitqueue_head(&isp->isp_osinfo.t_actions[i].thread_waiter);
+ if (i < MAX_THREAD_ACTION - 1) {
+ isp->isp_osinfo.t_actions[i].next = &isp->isp_osinfo.t_actions[i+1];
+ }
+ }
+ isp->isp_osinfo.t_busy = NULL;
+ isp->isp_osinfo.t_busy_t = NULL;
+ isp->isp_osinfo.t_free = isp->isp_osinfo.t_actions;
+
#ifdef ISP_TARGET_MODE
/*
* Initialize target stuff here
@@ -4264,7 +4278,14 @@
* Start watchdog timer, create FC handler thread and reinit hardware.
*/
if (IS_FC(isp)) {
- ISP_THREAD_EXEC(isp);
+ isp->isp_osinfo.thread_task = kthread_run(isp_task_thread, isp, "isp%d_fc", isp->isp_unit);
+ if (IS_ERR(isp->isp_osinfo.thread_task)) {
+ isp_prt(isp, ISP_LOGERR, "unable to start FC task thread");
+#ifdef ISP_TARGET_MODE
+ isp_deinit_target(isp);
+#endif
+ isp->isp_osinfo.thread_task = NULL;
+ }
}
ISP_LOCK_SOFTC(isp);
@@ -4278,14 +4299,14 @@
retval = isplinux_reinit(isp);
if (retval) {
- isp_prt(isp, ISP_LOGWARN, "failed to init HBA port (%d): skipping it", retval);
+ isp_prt(isp, ISP_LOGERR, "failed to init HBA port (%d): skipping it", retval);
del_timer(&isp->isp_osinfo.timer);
isp->dogactive = 0;
ISP_UNLK_SOFTC(isp);
#ifdef ISP_TARGET_MODE
isp_deinit_target(isp);
#endif
- ISP_THREAD_KILL(isp);
+ kthread_stop(isp->isp_osinfo.thread_task);
return (-1);
}
ISP_UNLK_SOFTC(isp);
@@ -4391,23 +4412,14 @@
int
isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *file, const int line)
{
- DECLARE_MUTEX_LOCKED(sem);
- int i;
isp_thread_action_t *tap;
unsigned long flags;
spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
- if (isp->isp_osinfo.task_active == 0) {
- spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
- isp_prt(isp, ISP_LOGERR, "thread event %d from %s:%d sent when thread gone", action, file, line);
- return (-1);
- }
-
/*
* Check for duplicates
*/
- for (i = 0; i < isp->isp_osinfo.nt_actions; i++) {
- tap = &isp->isp_osinfo.t_actions[i];
+ for (tap = isp->isp_osinfo.t_busy; tap != NULL; tap = tap->next) {
if (tap->thread_action == action && tap->arg == a && dowait == 0) {
tap->count++;
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
@@ -4415,29 +4427,49 @@
return (0);
}
}
- if (isp->isp_osinfo.nt_actions >= MAX_THREAD_ACTION) {
+ if ((tap = isp->isp_osinfo.t_free) == NULL) {
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
isp_prt(isp, ISP_LOGERR, "thread event %d from %s:%d sent with thread overflow", action, file, line);
return (-1);
}
- tap = &isp->isp_osinfo.t_actions[isp->isp_osinfo.nt_actions++];
+ isp->isp_osinfo.t_free = tap->next;
+ tap->next = NULL;
tap->count = 1;
tap->thread_action = action;
tap->arg = a;
+ tap->done = 0;
if (dowait) {
- tap->thread_waiter = &sem;
+ tap->waiting = 1;
+ isp_prt(isp, ISP_LOGDEBUG0, "action %d sending from %s:%d and now waiting", action, file, line);
} else {
- tap->thread_waiter = 0;
+ tap->waiting = 0;
+ isp_prt(isp, ISP_LOGDEBUG0, "action %d from %s:%d sending", action, file, line);
}
- ISP_THREAD_WAKE(isp);
+ if (isp->isp_osinfo.t_busy) {
+ isp->isp_osinfo.t_busy_t->next = tap;
+ } else {
+ isp->isp_osinfo.t_busy = tap;
+ }
+ isp->isp_osinfo.t_busy_t = tap;
+ spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
+ wake_up(&isp->isp_osinfo.trq);
if (dowait) {
- isp_prt(isp, ISP_LOGDEBUG1, "action %d sent from %s:%d and now waiting", action, file, line);
+ while (wait_event_interruptible_timeout(tap->thread_waiter, (tap->done == 1), 100)) {
+ if (kthread_should_stop()) {
+ break;
+ }
+ }
+ if (kthread_should_stop()) {
+ tap->waiting = 0;
+ return (-1);
+ }
+ spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
+ tap->waiting = 0;
+ tap->next = isp->isp_osinfo.t_free;
+ isp->isp_osinfo.t_free = tap;
+ tap->next = NULL;
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
- down(&sem);
- isp_prt(isp, ISP_LOGDEBUG1, "action %d done", action);
- } else {
- spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
- isp_prt(isp, ISP_LOGDEBUG1, "action %d from %s:%d sent", action, file, line);
+ isp_prt(isp, ISP_LOGDEBUG0, "action %d from %s:%d done", action, file, line);
}
return (0);
}
@@ -4446,372 +4478,362 @@
isp_task_thread(void *arg)
{
ispsoftc_t *isp = arg;
+ isp_thread_action_t *tap;
unsigned long flags;
- int action, nactions, i;
- isp_thread_action_t curactions[MAX_THREAD_ACTION];
+ int i;
- lock_kernel();
- daemonize("%s_thrd%d", ISP_NAME, isp->isp_unit);
- unlock_kernel();
- siginitsetinv(¤t->blocked, 0);
- ISP_THREAD_IACK(isp);
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread starting");
-
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread starting");
-
- for (;;) {
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread sleeping");
- ISP_THREAD_WAIT(isp);
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread running");
- spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
- if (signal_pending(current)) {
- isp_prt(isp, ISP_LOGALL, "%s received signal (%d)", current->comm, signal_pending(current));
- flush_signals(current);
- if (isp->isp_osinfo.task_active) {
- spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
- continue;
- }
+ while (!kthread_should_stop()) {
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread sleeping");
+ if (wait_event_interruptible(isp->isp_osinfo.trq, (isp->isp_osinfo.t_busy || kthread_should_stop()))) {
+ continue;
}
- if (isp->isp_osinfo.task_active == 0) {
- spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread running");
+ if (kthread_should_stop()) {
break;
}
- nactions = isp->isp_osinfo.nt_actions;
- isp->isp_osinfo.nt_actions = 0;
- for (action = 0; action < nactions; action++) {
- curactions[action] = isp->isp_osinfo.t_actions[action];
+ spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
+ if ((tap = isp->isp_osinfo.t_busy) != NULL) {
+ if ((isp->isp_osinfo.t_busy = tap->next) == NULL) {
+ isp->isp_osinfo.t_busy_t = NULL;
+ }
}
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
-
- for (action = 0; action < nactions; action++) {
- isp_thread_action_t *tap = &curactions[action];
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread[%d]: action %d (%p)", action, tap->thread_action, tap->thread_waiter);
- switch (tap->thread_action) {
- case ISP_THREAD_NIL:
- break;
- case ISP_THREAD_SCSI_SCAN:
- {
+ if (tap == NULL) {
+ continue;
+ }
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread: action %d", tap->thread_action);
+ switch (tap->thread_action) {
+ case ISP_THREAD_NIL:
+ break;
+ case ISP_THREAD_SCSI_SCAN:
+ {
/* this gets pegged in isplinux_queuecommand, even for async scanning */
#if 0
- unsigned long arg = (unsigned long) tap->arg;
- int tgt, chan, rescan;
- tgt = arg & 0xffff;
- chan = (arg >> 16) & 0xff;
- rescan = (arg >> 31) & 1;
- scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, SCAN_WILD_CARD, rescan);
+ unsigned long arg = (unsigned long) tap->arg;
+ int tgt, chan, rescan;
+ tgt = arg & 0xffff;
+ chan = (arg >> 16) & 0xff;
+ rescan = (arg >> 31) & 1;
+ scsi_scan_target(&isp->isp_osinfo.host->shost_gendev, chan, tgt, SCAN_WILD_CARD, rescan);
#endif
+ break;
+ }
+ case ISP_THREAD_REINIT:
+ ISP_LOCKU_SOFTC(isp);
+ if (isp->isp_dead) {
+ isp_prt(isp, ISP_LOGERR, "chip marked dead- not restarting");
+ isp_shutdown(isp);
+ ISP_DISABLE_INTS(isp);
+ ISP_UNLKU_SOFTC(isp);
break;
}
- case ISP_THREAD_REINIT:
- ISP_LOCKU_SOFTC(isp);
- if (isp->isp_dead) {
- isp_prt(isp, ISP_LOGERR, "chip marked dead- not restarting");
- isp_shutdown(isp);
- ISP_DISABLE_INTS(isp);
- ISP_UNLKU_SOFTC(isp);
- break;
+ isp_reinit(isp);
+ if (isp->isp_state == ISP_RUNSTATE) {
+ for (i = 0; i < isp->isp_nchan; i++) {
+ ISP_DATA(isp, i)->blocked = 0;
}
- isp_reinit(isp);
- if (isp->isp_state == ISP_RUNSTATE) {
- for (i = 0; i < isp->isp_nchan; i++) {
- ISP_DATA(isp, i)->blocked = 0;
- }
- isp_async(isp, ISPASYNC_FW_RESTARTED);
- } else {
- isp_prt(isp, ISP_LOGERR, "unable to restart chip");
+ isp_async(isp, ISPASYNC_FW_RESTARTED);
+ } else {
+ isp_prt(isp, ISP_LOGERR, "unable to restart chip");
+ }
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ case ISP_THREAD_FC_RESCAN:
+ {
+ fcparam *fcp = tap->arg;
+ int chan = fcp - FCPARAM(isp, 0);
+
+ fcp = FCPARAM(isp, chan);
+ ISP_LOCKU_SOFTC(isp);
+ ISP_DATA(isp, chan)->fcrswdog = 0;
+ if (isp_fc_runstate(isp, chan, 250000) == 0) {
+ ISP_DATA(isp, chan)->deadloop = 0;
+ ISP_DATA(isp, chan)->downcount = 0;
+ ISP_DATA(isp, chan)->blocked = 0;
+ isplinux_runwaitq(isp);
+ } else {
+ if (ISP_DATA(isp, chan)->downcount == 0) {
+ ISP_DATA(isp, chan)->downcount = jiffies;
}
- ISP_UNLKU_SOFTC(isp);
- break;
- case ISP_THREAD_FC_RESCAN:
- {
- fcparam *fcp = tap->arg;
- int chan = fcp - FCPARAM(isp, 0);
-
- fcp = FCPARAM(isp, chan);
- ISP_LOCKU_SOFTC(isp);
- ISP_DATA(isp, chan)->fcrswdog = 0;
- if (isp_fc_runstate(isp, chan, 250000) == 0) {
- ISP_DATA(isp, chan)->deadloop = 0;
+ /*
+ * Try again in a little while.
+ */
+ if ((jiffies - ISP_DATA(isp, chan)->downcount) > (isp_deadloop_time * HZ)) {
+ fcp->loop_seen_once = 0;
+ ISP_DATA(isp, chan)->deadloop = 1;
ISP_DATA(isp, chan)->downcount = 0;
ISP_DATA(isp, chan)->blocked = 0;
- isplinux_runwaitq(isp);
+ isp_prt(isp, ISP_LOGWARN, "Chan %d assuming loop is dead", chan);
+ isplinux_flushwaitq(isp);
} else {
- if (ISP_DATA(isp, chan)->downcount == 0) {
- ISP_DATA(isp, chan)->downcount = jiffies;
- }
- /*
- * Try again in a little while.
- */
- if ((jiffies - ISP_DATA(isp, chan)->downcount) > (isp_deadloop_time * HZ)) {
- fcp->loop_seen_once = 0;
- ISP_DATA(isp, chan)->deadloop = 1;
- ISP_DATA(isp, chan)->downcount = 0;
- ISP_DATA(isp, chan)->blocked = 0;
- isp_prt(isp, ISP_LOGWARN, "Chan %d assuming loop is dead", chan);
- isplinux_flushwaitq(isp);
- } else {
- ISP_DATA(isp, chan)->fcrswdog = 1;
- }
+ ISP_DATA(isp, chan)->fcrswdog = 1;
}
- ISP_UNLKU_SOFTC(isp);
- break;
}
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
#ifdef ISP_TARGET_MODE
- case ISP_THREAD_LOGOUT:
- {
- mbreg_t mbs;
- union {
- isp_pdb_t pdb;
- int id;
- } u;
- fcportdb_t *lp = tap->arg;
+ case ISP_THREAD_LOGOUT:
+ {
+ mbreg_t mbs;
+ union {
+ isp_pdb_t pdb;
+ int id;
+ } u;
+ fcportdb_t *lp = tap->arg;
- ISP_LOCKU_SOFTC(isp);
- if (lp->state != FC_PORTDB_STATE_VALID) {
- isp_prt(isp, ISP_LOGALL, "target entry no longer valid");
- ISP_UNLKU_SOFTC(isp);
- break;
- }
- MEMZERO(&u, sizeof (u));
- u.id = lp->handle;
- isp_prt(isp, ISP_LOGALL, "Doing Port Logout repair for 0x%016llx@0x%x (loop id) %u",
- lp->port_wwn, lp->portid, lp->handle);
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGOUT;
- if (ISP_CAP_2KLOGIN(isp)) {
- mbs.param[1] = lp->handle;
- mbs.obits |= (1 << 10);
- } else {
- mbs.param[1] = lp->handle << 8;
- }
- mbs.logval = MBLOGNONE;
- (void) isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "failed to get logout loop id %u", lp->handle);
- lp->state = FC_PORTDB_STATE_PROBATIONAL;
- ISP_UNLKU_SOFTC(isp);
- break;
- }
- MEMZERO(&mbs, sizeof (mbs));
- mbs.param[0] = MBOX_FABRIC_LOGIN;
- if (ISP_CAP_2KLOGIN(isp)) {
- mbs.param[1] = lp->handle;
- mbs.obits |= (1 << 10);
- } else {
- mbs.param[1] = lp->handle << 8;
- }
- mbs.param[2] = lp->portid >> 16;
- mbs.param[3] = lp->portid & 0xffff;
- (void) isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
- if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "failed to get login port id %x at loop id %u", lp->portid, lp->handle);
- lp->state = FC_PORTDB_STATE_PROBATIONAL;
- ISP_UNLKU_SOFTC(isp);
- break;
- }
- lp->state = FC_PORTDB_STATE_VALID;
+ ISP_LOCKU_SOFTC(isp);
+ if (lp->state != FC_PORTDB_STATE_VALID) {
+ isp_prt(isp, ISP_LOGTINFO, "target mode entry no longer valid");
ISP_UNLKU_SOFTC(isp);
break;
}
- case ISP_THREAD_FINDIID:
- {
- tmd_cmd_t *tmd = tap->arg;
- fcportdb_t *lp = NULL;
- uint64_t iid = INI_NONE;
- uint16_t nphdl = NIL_HANDLE;
+ MEMZERO(&u, sizeof (u));
+ u.id = lp->handle;
+ isp_prt(isp, ISP_LOGTINFO, "Doing Port Logout repair for 0x%016llx@0x%x (loop id) %u",
+ lp->port_wwn, lp->portid, lp->handle);
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_FABRIC_LOGOUT;
+ if (ISP_CAP_2KLOGIN(isp)) {
+ mbs.param[1] = lp->handle;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = lp->handle << 8;
+ }
+ mbs.logval = MBLOGNONE;
+ (void) isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, "failed to get logout loop id %u", lp->handle);
+ lp->state = FC_PORTDB_STATE_PROBATIONAL;
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ MEMZERO(&mbs, sizeof (mbs));
+ mbs.param[0] = MBOX_FABRIC_LOGIN;
+ if (ISP_CAP_2KLOGIN(isp)) {
+ mbs.param[1] = lp->handle;
+ mbs.obits |= (1 << 10);
+ } else {
+ mbs.param[1] = lp->handle << 8;
+ }
+ mbs.param[2] = lp->portid >> 16;
+ mbs.param[3] = lp->portid & 0xffff;
+ (void) isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
+ if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+ isp_prt(isp, ISP_LOGERR, "failed to get login port id %x at loop id %u", lp->portid, lp->handle);
+ lp->state = FC_PORTDB_STATE_PROBATIONAL;
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ lp->state = FC_PORTDB_STATE_VALID;
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ case ISP_THREAD_FINDIID:
+ {
+ tmd_cmd_t *tmd = tap->arg;
+ fcportdb_t *lp = NULL;
+ uint64_t iid = INI_NONE;
+ uint16_t nphdl = NIL_HANDLE;
- if (tmd->cd_lflags & CDFL_ABORTED) {
- isp_prt(isp, ISP_LOGTINFO, "[%llx] asking thread to terminate because it was marked aborted", (unsigned long long) tmd->cd_tagval);
- ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
- break;
- }
- ISP_LOCKU_SOFTC(isp);
- if (isp_find_pdb_by_sid(isp, tmd->cd_channel, tmd->cd_portid, &lp)) {
- if (!VALID_INI(lp->port_wwn)) {
- if (lp->handle == NIL_HANDLE) {
- /*
- * Ooops- all we have is the port id.
- */
- uint16_t nphdl, max;
- isp_pdb_t pdb;
+ if (tmd->cd_lflags & CDFL_ABORTED) {
+ isp_prt(isp, ISP_LOGTINFO, "[%llx] asking thread to terminate because it was marked aborted", (unsigned long long) tmd->cd_tagval);
+ isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
+ break;
+ }
+ ISP_LOCKU_SOFTC(isp);
+ if (isp_find_pdb_by_sid(isp, tmd->cd_channel, tmd->cd_portid, &lp)) {
+ if (!VALID_INI(lp->port_wwn)) {
+ if (lp->handle == NIL_HANDLE) {
+ /*
+ * Ooops- all we have is the port id.
+ */
+ uint16_t nphdl, max;
+ isp_pdb_t pdb;
- if (IS_24XX(isp)) {
- max = NPH_MAX_2K;
- } else {
- max = NPH_MAX;
+ if (IS_24XX(isp)) {
+ max = NPH_MAX_2K;
+ } else {
+ max = NPH_MAX;
+ }
+ for (nphdl = 0; nphdl != max; nphdl++) {
+ if (isp_control(isp, ISPCTL_GET_PDB, tmd->cd_channel, nphdl, &pdb)) {
+ continue;
}
- for (nphdl = 0; nphdl != max; nphdl++) {
- if (isp_control(isp, ISPCTL_GET_PDB, tmd->cd_channel, nphdl, &pdb)) {
- continue;
- }
- isp_prt(isp, ISP_LOGTINFO, "%s: nphdl 0x%04x has portid 0x%06x", __FUNCTION__, nphdl, pdb.portid);
- if (pdb.portid == tmd->cd_portid) {
- lp->handle = nphdl;
- break;
- }
- }
- if (nphdl == max) {
- ISP_UNLKU_SOFTC(isp);
- isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because because we can't find the N-Port handle", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff);
- isp_tgt_dump_pdb(isp, tmd->cd_channel);
- ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
+ isp_prt(isp, ISP_LOGTINFO, "%s: nphdl 0x%04x has portid 0x%06x", __FUNCTION__, nphdl, pdb.portid);
+ if (pdb.portid == tmd->cd_portid) {
+ lp->handle = nphdl;
break;
}
}
- if (isp_control(isp, ISPCTL_GET_NAMES, tmd->cd_channel, lp->handle, NULL, &lp->port_wwn) == 0) {
- nphdl = lp->handle;
- iid = lp->port_wwn;
- } else {
- isp_prt(isp, ISP_LOGALL, "%s: Chan %d [0x%llx] failed to get name for handle 0x%02x for portid 0x%06x", __FUNCTION__, tmd->cd_channel, tmd->cd_tagval, lp->handle, tmd->cd_portid);
+ if (nphdl == max) {
+ ISP_UNLKU_SOFTC(isp);
+ isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because because we can't find the N-Port handle", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff);
+ isp_tgt_dump_pdb(isp, tmd->cd_channel);
+ isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
+ break;
}
- } else {
+ }
+ if (isp_control(isp, ISPCTL_GET_NAMES, tmd->cd_channel, lp->handle, NULL, &lp->port_wwn) == 0) {
nphdl = lp->handle;
iid = lp->port_wwn;
+ } else {
+ isp_prt(isp, ISP_LOGALL, "%s: Chan %d [0x%llx] failed to get name for handle 0x%02x for portid 0x%06x", __FUNCTION__, tmd->cd_channel, tmd->cd_tagval, lp->handle, tmd->cd_portid);
}
} else {
- /*
- * If it's no longer in the port database, then some event between the receipt of the command and now
- * has cleared it out. The command is probably already dead due to initiator port logout.
- */
- ISP_UNLKU_SOFTC(isp);
- isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because PortID 0x%06x no longer in port database", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_portid);
- isp_tgt_dump_pdb(isp, tmd->cd_channel);
- ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
- break;
+ nphdl = lp->handle;
+ iid = lp->port_wwn;
}
- if (iid == INI_NONE) {
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: [0x%llx] trying to find IID again...", __FUNCTION__, tmd->cd_tagval);
- tmd->cd_next = isp->isp_osinfo.waiting_t;
- isp->isp_osinfo.waiting_t = tmd;
- tmd->cd_lastoff = 0;
- ISP_UNLKU_SOFTC(isp);
- break;
- }
- tmd->cd_tgt = FCPARAM(isp, tmd->cd_channel)->isp_wwpn;
- tmd->cd_nphdl = nphdl;
- tmd->cd_iid = iid;
- isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__,
- tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid);
- CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
+ } else {
+ /*
+ * If it's no longer in the port database, then some event between the receipt of the command and now
+ * has cleared it out. The command is probably already dead due to initiator port logout.
+ */
ISP_UNLKU_SOFTC(isp);
- isp_tgt_tq(isp);
+ isp_prt(isp, ISP_LOGTINFO, "[0x%llx] asking thread to terminate cmd [0x%02x] because PortID 0x%06x no longer in port database", tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_portid);
+ isp_tgt_dump_pdb(isp, tmd->cd_channel);
+ isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
break;
}
- case ISP_THREAD_FINDPORTID:
- {
- tmd_cmd_t *tmd = tap->arg;
- fcportdb_t *lp;
+ if (iid == INI_NONE) {
+ isp_prt(isp, ISP_LOGTDEBUG0, "%s: [0x%llx] trying to find IID again...", __FUNCTION__, tmd->cd_tagval);
+ tmd->cd_next = isp->isp_osinfo.waiting_t;
+ isp->isp_osinfo.waiting_t = tmd;
+ tmd->cd_lastoff = 0;
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ tmd->cd_tgt = FCPARAM(isp, tmd->cd_channel)->isp_wwpn;
+ tmd->cd_nphdl = nphdl;
+ tmd->cd_iid = iid;
+ isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__,
+ tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid);
+ CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
+ ISP_UNLKU_SOFTC(isp);
+ isp_tgt_tq(isp);
+ break;
+ }
+ case ISP_THREAD_FINDPORTID:
+ {
+ tmd_cmd_t *tmd = tap->arg;
+ fcportdb_t *lp;
- ISP_LOCKU_SOFTC(isp);
- if (isp_find_pdb_by_loopid(isp, tmd->cd_channel, tmd->cd_nphdl, &lp)) {
- if (lp->portid == PORT_NONE) {
- isp_pdb_t pdb;
- if (isp_control(isp, ISPCTL_GET_PDB, tmd->cd_channel, tmd->cd_nphdl, &pdb) == 0) {
- tmd->cd_portid = lp->portid = pdb.portid;
- }
- } else {
- tmd->cd_portid = lp->portid;
+ ISP_LOCKU_SOFTC(isp);
+ if (isp_find_pdb_by_loopid(isp, tmd->cd_channel, tmd->cd_nphdl, &lp)) {
+ if (lp->portid == PORT_NONE) {
+ isp_pdb_t pdb;
+ if (isp_control(isp, ISPCTL_GET_PDB, tmd->cd_channel, tmd->cd_nphdl, &pdb) == 0) {
+ tmd->cd_portid = lp->portid = pdb.portid;
}
} else {
- isp_prt(isp, ISP_LOGTINFO, "[0x%llx] not in port database at all any more", tmd->cd_tagval);
+ tmd->cd_portid = lp->portid;
}
- if (tmd->cd_portid != PORT_NONE) {
- isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__,
- tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid);
- }
+ } else {
+ isp_prt(isp, ISP_LOGTINFO, "[0x%llx] not in port database at all any more", tmd->cd_tagval);
+ }
+ if (tmd->cd_portid != PORT_NONE) {
+ isp_prt(isp, ISP_LOGTINFO, "%s: [0x%llx] Chan %d found initiator @ IID 0x%016llx N-Port Handle 0x%02x Port ID 0x%06x", __FUNCTION__,
+ tmd->cd_tagval, tmd->cd_channel, (unsigned long long)tmd->cd_iid, tmd->cd_nphdl, tmd->cd_portid);
+ }
+ CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
+ ISP_UNLKU_SOFTC(isp);
+ isp_tgt_tq(isp);
+ break;
+ }
+ case ISP_THREAD_TERMINATE:
+ {
+ fcportdb_t *lp;
+ tmd_cmd_t *tmd = tap->arg;
+
+ ISP_LOCKU_SOFTC(isp);
+ if (isp_find_pdb_by_sid(isp, tmd->cd_channel, tmd->cd_portid, &lp)) {
+ tmd->cd_iid = lp->port_wwn;
+ tmd->cd_nphdl = lp->handle;
CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
ISP_UNLKU_SOFTC(isp);
isp_tgt_tq(isp);
+ isp_prt(isp, ISP_LOGINFO, "Chan %d [%llx] reprieved", (int) AT2_GET_BUS(tmd->cd_tagval), (unsigned long long) tmd->cd_tagval);
break;
}
- case ISP_THREAD_TERMINATE:
- {
- fcportdb_t *lp;
- tmd_cmd_t *tmd = tap->arg;
- ISP_LOCKU_SOFTC(isp);
- if (isp_find_pdb_by_sid(isp, tmd->cd_channel, tmd->cd_portid, &lp)) {
- tmd->cd_iid = lp->port_wwn;
- tmd->cd_nphdl = lp->handle;
- CALL_PARENT_TMD(isp, tmd, QOUT_TMD_START);
- ISP_UNLKU_SOFTC(isp);
- isp_tgt_tq(isp);
- isp_prt(isp, ISP_LOGINFO, "Chan %d [%llx] reprieved", (int) AT2_GET_BUS(tmd->cd_tagval), (unsigned long long) tmd->cd_tagval);
- break;
- }
-
- isp_prt(isp, ISP_LOGTINFO, "%s now terminating [%llx] from 0x%06x", __FUNCTION__, (unsigned long long) tmd->cd_tagval, tmd->cd_portid);
- if (isp_terminate_cmd(isp, tmd)) {
- ISP_UNLKU_SOFTC(isp);
- ISP_THREAD_EVENT(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
- break;
- }
- tmd->cd_next = NULL;
- if (isp->isp_osinfo.tfreelist) {
- isp->isp_osinfo.bfreelist->cd_next = tmd;
- } else {
- isp->isp_osinfo.tfreelist = tmd;
- }
- isp->isp_osinfo.bfreelist = tmd;
+ isp_prt(isp, ISP_LOGTINFO, "%s now terminating [%llx] from 0x%06x", __FUNCTION__, (unsigned long long) tmd->cd_tagval, tmd->cd_portid);
+ if (isp_terminate_cmd(isp, tmd)) {
ISP_UNLKU_SOFTC(isp);
+ isp_thread_event(isp, ISP_THREAD_TERMINATE, tmd, 0, __FUNCTION__, __LINE__);
break;
}
- case ISP_THREAD_RESTART_AT7:
- {
- at7_entry_t at;
- tmd_cmd_t *tmd = tap->arg;
- MEMCPY(&at, tmd, sizeof (at7_entry_t));
- ISP_LOCKU_SOFTC(isp);
- MEMZERO(tmd, sizeof (tmd_cmd_t));
- if (isp->isp_osinfo.tfreelist) {
- isp->isp_osinfo.bfreelist->cd_next = tmd;
- } else {
- isp->isp_osinfo.tfreelist = tmd;
- }
- isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */
- isp_handle_platform_atio7(isp, &at);
- ISP_UNLKU_SOFTC(isp);
- break;
+ tmd->cd_next = NULL;
+ if (isp->isp_osinfo.tfreelist) {
+ isp->isp_osinfo.bfreelist->cd_next = tmd;
+ } else {
+ isp->isp_osinfo.tfreelist = tmd;
}
- case ISP_THREAD_FC_PUTBACK:
- {
- tmd_cmd_t *tmd = tap->arg;
- ISP_LOCKU_SOFTC(isp);
- isp_prt(isp, ISP_LOGTINFO, "%s: [%llx] calling putback", __FUNCTION__, tmd->cd_tagval);
- if (isp_target_putback_atio(isp, tmd)) {
- ISP_UNLKU_SOFTC(isp);
- ISP_THREAD_EVENT(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__);
- break;
- }
- if (tmd->cd_lflags & CDFL_NEED_CLNUP) {
- tmd->cd_lflags ^= CDFL_NEED_CLNUP;
- isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (unsigned long long) tmd->cd_tagval);
- (void) isp_terminate_cmd(isp, tmd);
- }
- MEMZERO(tmd, sizeof (tmd_cmd_t));
- if (isp->isp_osinfo.tfreelist) {
- isp->isp_osinfo.bfreelist->cd_next = tmd;
- } else {
- isp->isp_osinfo.tfreelist = tmd;
- }
- isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */
- isp_prt(isp, ISP_LOGTDEBUG0, "DONE freeing tmd %p [%llx] after retry", tmd, tmd->cd_tagval);
+ isp->isp_osinfo.bfreelist = tmd;
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ case ISP_THREAD_RESTART_AT7:
+ {
+ at7_entry_t at;
+ tmd_cmd_t *tmd = tap->arg;
+ MEMCPY(&at, tmd, sizeof (at7_entry_t));
+ ISP_LOCKU_SOFTC(isp);
+ MEMZERO(tmd, sizeof (tmd_cmd_t));
+ if (isp->isp_osinfo.tfreelist) {
+ isp->isp_osinfo.bfreelist->cd_next = tmd;
+ } else {
+ isp->isp_osinfo.tfreelist = tmd;
+ }
+ isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */
+ isp_handle_platform_atio7(isp, &at);
+ ISP_UNLKU_SOFTC(isp);
+ break;
+ }
+ case ISP_THREAD_FC_PUTBACK:
+ {
+ tmd_cmd_t *tmd = tap->arg;
+ ISP_LOCKU_SOFTC(isp);
+ isp_prt(isp, ISP_LOGTINFO, "%s: [%llx] calling putback", __FUNCTION__, tmd->cd_tagval);
+ if (isp_target_putback_atio(isp, tmd)) {
ISP_UNLKU_SOFTC(isp);
+ isp_thread_event(isp, ISP_THREAD_FC_PUTBACK, tmd, 0, __FUNCTION__, __LINE__);
break;
}
-#endif
- default:
- break;
+ if (tmd->cd_lflags & CDFL_NEED_CLNUP) {
+ tmd->cd_lflags ^= CDFL_NEED_CLNUP;
+ isp_prt(isp, ISP_LOGTINFO, "Terminating %llx too", (unsigned long long) tmd->cd_tagval);
+ (void) isp_terminate_cmd(isp, tmd);
}
-
- if (tap->thread_waiter) {
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread signalling %p", tap->thread_waiter);
- up(tap->thread_waiter);
+ MEMZERO(tmd, sizeof (tmd_cmd_t));
+ if (isp->isp_osinfo.tfreelist) {
+ isp->isp_osinfo.bfreelist->cd_next = tmd;
+ } else {
+ isp->isp_osinfo.tfreelist = tmd;
}
+ isp->isp_osinfo.bfreelist = tmd; /* remember to move the list tail pointer */
+ isp_prt(isp, ISP_LOGTDEBUG0, "DONE freeing tmd %p [%llx] after retry", tmd, tmd->cd_tagval);
+ ISP_UNLKU_SOFTC(isp);
+ break;
}
+#endif
+ default:
+ break;
+ }
+ tap->done = 0;
+ if (tap->waiting) {
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread signalling");
+ tap->waiting = 0;
+ wake_up(&tap->thread_waiter);
+ } else {
+ spin_lock_irqsave(&isp->isp_osinfo.tlock, flags);
+ tap->next = isp->isp_osinfo.t_free;
+ isp->isp_osinfo.t_free = tap;
+ spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
+ }
}
- isp_prt(isp, ISP_LOGDEBUG1, "isp_task_thread exiting");
- ISP_THREAD_XACK(isp);
+ isp_prt(isp, ISP_LOGDEBUG0, "isp_task_thread exiting");
return (0);
}
Modified: trunk/qla_isp/linux/isp_linux.h
===================================================================
--- trunk/qla_isp/linux/isp_linux.h 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/isp_linux.h 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp_linux.h,v 1.160 2008/03/15 18:16:47 mjacob Exp $ */
+/* $Id: isp_linux.h,v 1.161 2008/04/15 22:41:03 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -94,6 +94,7 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
+#include <linux/kthread.h>
#include <linux/stat.h>
#include <linux/pci.h>
#include <asm/dma.h>
@@ -264,7 +265,9 @@
#define ISP_CT_TIMEOUT 120
#endif /* ISP_TARGET_MODE */
-typedef struct {
+typedef struct isp_thread_action isp_thread_action_t;
+struct isp_thread_action {
+ isp_thread_action_t *next;
enum {
ISP_THREAD_NIL=1,
ISP_THREAD_FC_RESCAN,
@@ -279,9 +282,12 @@
ISP_THREAD_SCSI_SCAN,
} thread_action;
void * arg;
- struct semaphore * thread_waiter;
- int count;
-} isp_thread_action_t;
+ wait_queue_head_t thread_waiter;
+ uint32_t
+ waiting : 1,
+ done : 1,
+ count : 30;
+};
#define MAX_THREAD_ACTION 128
#define MAX_FC_CHAN 128
@@ -289,6 +295,7 @@
struct isposinfo {
struct Scsi_Host * host;
+ unsigned int device_id;
u32 mcorig; /* original maxcmds */
void *device; /* hardware device structure */
Scsi_Cmnd *wqnext, *wqtail;
@@ -309,13 +316,12 @@
struct timer_list mbtimer;
struct semaphore mbox_sem;
struct semaphore mbox_c_sem;
- struct semaphore fcs_sem;
spinlock_t slock;
unsigned volatile int
: 20,
dogcnt : 5,
isopen : 1,
- task_active : 1,
+ : 1,
dogactive : 1,
mboxcmd_done : 1,
mbox_waiting : 1,
@@ -323,12 +329,12 @@
intsok : 1;
u16 frame_size;
u16 exec_throttle;
+ struct task_struct *thread_task;
wait_queue_head_t trq;
- struct semaphore tcs;
spinlock_t tlock;
- unsigned int nt_actions;
- unsigned int device_id;
isp_thread_action_t t_actions[MAX_THREAD_ACTION];
+ isp_thread_action_t *t_free;
+ isp_thread_action_t *t_busy, *t_busy_t;
#ifdef ISP_TARGET_MODE
u32 isget : 16,
rstatus : 8,
@@ -364,47 +370,12 @@
#define dogactive isp_osinfo.dogactive
#define mbox_sem isp_osinfo.mbox_sem
#define mbox_c_sem isp_osinfo.mbox_c_sem
-#define fcs_sem isp_osinfo.fcs_sem
#define mbintsok isp_osinfo.mbintsok
#define intsok isp_osinfo.intsok
#define mbox_waiting isp_osinfo.mbox_waiting
#define mboxcmd_done isp_osinfo.mboxcmd_done
#define isp_isopen isp_osinfo.isopen
-#define ISP_THREAD_EXEC(x) \
- sema_init(&(x)->isp_osinfo.tcs, 0); \
- kernel_thread(isp_task_thread, (x), 0); \
- down(&isp->isp_osinfo.tcs)
-
-#define ISP_THREAD_IACK(x) \
- init_waitqueue_head(&(x)->isp_osinfo.trq); \
- (x)->isp_osinfo.task_active = 1; \
- up(&(x)->isp_osinfo.tcs)
-
-#define ISP_THREAD_WAIT(x) \
- wait_event_interruptible((x)->isp_osinfo.trq, (((x)->isp_osinfo.task_active == 0) || ((x)->isp_osinfo.nt_actions != 0)))
-
-#define ISP_THREAD_EVENT isp_thread_event
-
-#define ISP_THREAD_WAKE(x) wake_up_all(&(x)->isp_osinfo.trq)
-
-#define ISP_THREAD_KILL(x) \
- { \
- unsigned long _fl; \
- spin_lock_irqsave(&(x)->isp_osinfo.tlock, _fl); \
- if ((x)->isp_osinfo.task_active) { \
- sema_init(&(x)->isp_osinfo.tcs, 0); \
- (x)->isp_osinfo.task_active = 0; \
- wake_up_all(&(x)->isp_osinfo.trq); \
- spin_unlock_irqrestore(&(x)->isp_osinfo.tlock, _fl); \
- down(&(x)->isp_osinfo.tcs); \
- } else { \
- spin_unlock_irqrestore(&(x)->isp_osinfo.tlock, _fl); \
- } \
- }
-
-#define ISP_THREAD_XACK(x) up(&(x)->isp_osinfo.tcs)
-
/*
* Locking macros...
*/
@@ -467,7 +438,7 @@
# endif
#endif
-#define MBOX_ACQUIRE mbox_acquire
+#define MBOX_ACQUIRE(isp) down_trylock(&isp->mbox_sem)
#define MBOX_WAIT_COMPLETE mbox_wait_complete
#define MBOX_NOTIFY_COMPLETE(isp) \
if (isp->mbox_waiting) { \
@@ -668,7 +639,6 @@
static inline unsigned long _usec_to_jiffies(unsigned int);
static inline unsigned long _jiffies_to_usec(unsigned long);
static inline int isplinux_tagtype(Scsi_Cmnd *);
-static inline int mbox_acquire(ispsoftc_t *);
static inline void mbox_wait_complete(ispsoftc_t *, mbreg_t *);
int isplinux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
@@ -824,25 +794,6 @@
}
}
-static inline int
-mbox_acquire(ispsoftc_t *isp)
-{
- /*
- * Try and acquire semaphore the easy way first-
- * with our lock already held.k
- */
- if (down_trylock(&isp->mbox_sem)) {
- if (ISP_ATOMIC()) {
- isp_prt(isp, ISP_LOGERR, "cannot acquire MBOX sema");
- return (1);
- }
- ISP_DROP_LK_SOFTC(isp);
- down(&isp->mbox_sem);
- ISP_IGET_LK_SOFTC(isp);
- }
- return (0);
-}
-
static inline void
mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
{
Modified: trunk/qla_isp/linux/isp_pci.c
===================================================================
--- trunk/qla_isp/linux/isp_pci.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/isp_pci.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: isp_pci.c,v 1.167 2008/03/23 17:05:10 mjacob Exp $ */
+/* $Id: isp_pci.c,v 1.168 2008/04/15 22:41:03 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -506,7 +506,7 @@
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
/**
* pci_intx - enables/disables PCI INTx for device dev
* @pdev: the PCI device to operate on
@@ -619,13 +619,7 @@
return (1);
}
- /* PCI Rev 2.3 changes */
- if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322) {
- /* enable PCI-INTX */
- pci_intx(pdev, 1);
- }
-
-
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432) {
struct msix_entry isp_msix[3];
int reg;
@@ -674,7 +668,12 @@
pectl |= (5 << 12); /* 4K READ BURST */
pci_write_config_word(pdev, reg + PCI_EXP_DEVCTL, pectl);
}
+ } else
+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ if (pci_enable_msi(pdev) == 0) {
+ isp_pci->msi_enabled = 1;
}
+#endif
/*
* Disable the ROM.
@@ -2845,7 +2844,7 @@
nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp));
if (nxti == optr) {
isp_pci_dmateardown(isp, Cmnd, 0);
- isp_prt(isp, ISP_LOGDEBUG0, "%s: out of space for continuations (%d of %d done)", __FUNCTION__, seg, segcnt);
+ isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __FUNCTION__, XS_CHANNEL(Cmnd), seg, segcnt);
XS_SETERR(Cmnd, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -3088,7 +3087,7 @@
nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp));
if (nxti == optr) {
isp_pci_dmateardown(isp, Cmnd, 0);
- isp_prt(isp, ISP_LOGWARN, "out of space for continuations (did %d of %d segments)", seg, segcnt);
+ isp_prt(isp, ISP_LOGDEBUG0, "%s: Chan %d out of space for continuations (did %d of %d segments)", __FUNCTION__, XS_CHANNEL(Cmnd), seg, segcnt);
XS_SETERR(Cmnd, HBA_BOTCH);
return (CMD_EAGAIN);
}
@@ -3396,7 +3395,7 @@
isp->isp_osinfo.device = pdev;
host->unique_id = isp_unit_seed++;
sprintf(isp->isp_name, "%s%d", ISP_NAME, isp->isp_unit);
- isp->isp_osinfo.device_id = ((pdev->bus->number) << 16) | (PCI_SLOT(pdev->devfn) << 8) | (PCI_FUNC(pdev->devfn));
+ isp->isp_osinfo.device_id = (pci_domain_nr(pdev->bus) << 16) | ((pdev->bus->number) << 8) | (PCI_SLOT(pdev->devfn) << 3) | (PCI_FUNC(pdev->devfn));
if (isp_disable & (1 << isp->isp_unit)) {
printk("%s: disabled at user request\n", isp->isp_name);
scsi_host_put(host);
@@ -3452,7 +3451,11 @@
#ifdef ISP_TARGET_MODE
isp_detach_target(isp);
#endif
- ISP_THREAD_KILL(isp);
+ if (isp->isp_osinfo.thread_task) {
+ wake_up(&isp->isp_osinfo.trq);
+ kthread_stop(isp->isp_osinfo.thread_task);
+ isp->isp_osinfo.thread_task = NULL;
+ }
ISP_LOCKU_SOFTC(isp);
isp_shutdown(isp);
isp->dogactive = 0;
Modified: trunk/qla_isp/linux/isp_scst.c
===================================================================
--- trunk/qla_isp/linux/isp_scst.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/isp_scst.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -150,7 +150,7 @@
module_param(debug, int, 0);
#else
#define SDprintk(fmt, args...)
-#define SDprintk2(fmt, args...)
+#define SDprintk2(fmt, args...)
#endif
#define Eprintk(fmt, args...) printk(KERN_ERR "isp_scst(%s): " fmt, __FUNCTION__, ##args)
Modified: trunk/qla_isp/linux/scsi_target.c
===================================================================
--- trunk/qla_isp/linux/scsi_target.c 2008-04-23 11:17:33 UTC (rev 354)
+++ trunk/qla_isp/linux/scsi_target.c 2008-04-24 06:34:08 UTC (rev 355)
@@ -1,4 +1,4 @@
-/* $Id: scsi_target.c,v 1.83 2008/03/15 18:16:47 mjacob Exp $ */
+/* $Id: scsi_target.c,v 1.84 2008/04/15 22:41:03 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reser...
[truncated message content] |