mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 02:31:27 +00:00
Synchronize with Feral CVS repository:
Add unit attention injection. Fix some ridiculous Sense things. Say why we couldn't pci register the driver. Make isp_thread_event return an int if it fails to send the event. If it fails to send the event, and this was for the 24XX card finding out the initiator for a command, return the command with a BUSY status. An N-port handle of zero is legal for a 24XX. Add some more special N-Port handle definitions for 2K f/w. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@265 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_target.c,v 1.71 2007/12/02 22:02:04 mjacob Exp $ */
|
||||
/* $Id: isp_target.c,v 1.72 2007/12/11 22:19:21 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -1378,7 +1378,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
|
||||
* Bus Device Reset message received or the SCSI Bus has
|
||||
* been Reset; the firmware has gone to Bus Free.
|
||||
*
|
||||
* The firmware generates an async mailbox interupt to
|
||||
* The firmware generates an async mailbox interrupt to
|
||||
* notify us of this and returns outstanding CTIOs with this
|
||||
* status. These CTIOs are handled in that same way as
|
||||
* CT_ABORTED ones, so just fall through here.
|
||||
@@ -1532,7 +1532,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
|
||||
/*
|
||||
* Target Reset function received.
|
||||
*
|
||||
* The firmware generates an async mailbox interupt to
|
||||
* The firmware generates an async mailbox interrupt to
|
||||
* notify us of this and returns outstanding CTIOs with this
|
||||
* status. These CTIOs are handled in that same way as
|
||||
* CT_ABORTED ones, so just fall through here.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: ispvar.h,v 1.87 2007/12/05 00:42:02 mjacob Exp $ */
|
||||
/* $Id: ispvar.h,v 1.88 2007/12/11 07:17:56 mjacob Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -272,7 +272,9 @@ typedef struct {
|
||||
#define NPH_RESERVED 0x7F0 /* begin of reserved N-port handles */
|
||||
#define NPH_MGT_ID 0x7FA /* Management Server Special ID */
|
||||
#define NPH_SNS_ID 0x7FC /* SNS Server Special ID */
|
||||
#define NPH_FL_ID 0x7FE /* FL Port Special ID */
|
||||
#define NPH_FABRIC_CTLR 0x7FD /* Fabric Controller (0xFFFFFD) */
|
||||
#define NPH_FL_ID 0x7FE /* F Port Special ID (0xFFFFFE) */
|
||||
#define NPH_IP_BCST 0x7ff /* IP Broadcast Special ID (0xFFFFFF) */
|
||||
#define NPH_MAX_2K 0x800
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile,v 1.5 2007/03/10 02:27:53 mjacob Exp $
|
||||
# $Id: Makefile,v 1.9 2007/12/11 22:19:39 mjacob Exp $
|
||||
#
|
||||
# Makefile
|
||||
#
|
||||
@@ -47,6 +47,9 @@ clean:
|
||||
install:
|
||||
@$(MAKE) -C ${LINUX} M=${CURDIR}/build modules_install
|
||||
|
||||
install_host_progs:
|
||||
@$(MAKE) -C build $@
|
||||
|
||||
links:
|
||||
@$(MAKE) -C build make_links
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_cb_ops.c,v 1.78 2007/12/02 22:02:06 mjacob Exp $ */
|
||||
/* $Id: isp_cb_ops.c,v 1.79 2007/12/11 22:18:05 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -744,7 +744,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
|
||||
case ISP_FC_GETDLIST:
|
||||
{
|
||||
isp_dlist_t *ua;
|
||||
uint16_t nph, nphs, nphe, count, chan, lim;
|
||||
uint16_t nph, nphe, count, chan, lim;
|
||||
struct wwnpair pair, *uptr;
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
@@ -770,12 +770,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
|
||||
} else {
|
||||
nphe = NPH_MAX;
|
||||
}
|
||||
if (IS_24XX(isp)) {
|
||||
nphs = 1;
|
||||
} else {
|
||||
nphs = 0;
|
||||
}
|
||||
for (count = 0, nph = nphs; count < lim && nph != nphe; nph++) {
|
||||
for (count = 0, nph = 0; count < lim && nph != nphe; nph++) {
|
||||
ISP_LOCKU_SOFTC(isp);
|
||||
rv = isp_control(isp, ISPCTL_GET_NAMES, chan, nph, &pair.wwnn, &pair.wwpn);
|
||||
ISP_UNLKU_SOFTC(isp);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_linux.c,v 1.212 2007/12/09 00:05:43 mjacob Exp $ */
|
||||
/* $Id: isp_linux.c,v 1.213 2007/12/11 22:19:07 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -1918,22 +1918,18 @@ isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
|
||||
}
|
||||
|
||||
if ((tmd = isp->isp_osinfo.tfreelist) == NULL) {
|
||||
/*
|
||||
* We're out of resources.
|
||||
*
|
||||
* Because we can't autofeed sense data back with a command for
|
||||
* parallel SCSI, we can't give back a CHECK CONDITION. We'll give
|
||||
* back a QUEUE FULL or BUSY status instead.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGWARN, "Chan %d is out of TMDs for command from initiator %d for lun %u",
|
||||
GET_BUS_VAL(aep->at_iid), GET_IID_VAL(aep->at_iid), aep->at_lun);
|
||||
if (aep->at_flags & AT_TQAE) {
|
||||
isp_endcmd(isp, aep, SCSI_QFULL, 0);
|
||||
} else {
|
||||
isp_endcmd(isp, aep, SCSI_BUSY, 0);
|
||||
if (isp->isp_osinfo.out_of_tmds == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "out of TMDs");
|
||||
isp->isp_osinfo.out_of_tmds = jiffies;
|
||||
}
|
||||
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__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
isp->isp_osinfo.out_of_tmds = 0;
|
||||
if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) {
|
||||
isp->isp_osinfo.bfreelist = NULL;
|
||||
}
|
||||
@@ -2014,14 +2010,18 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
|
||||
* If we're out of resources, just send a QFULL status back.
|
||||
*/
|
||||
if ((tmd = isp->isp_osinfo.tfreelist) == NULL) {
|
||||
isp_prt(isp, ISP_LOGWARN, "out of TMDs for command from 0x%016llx to lun %u",
|
||||
(((uint64_t) aep->at_wwpn[0]) << 48) |
|
||||
(((uint64_t) aep->at_wwpn[1]) << 32) |
|
||||
(((uint64_t) aep->at_wwpn[2]) << 16) |
|
||||
(((uint64_t) aep->at_wwpn[3]) << 0), lun);
|
||||
isp_endcmd(isp, aep, SCSI_QFULL, 0);
|
||||
if (isp->isp_osinfo.out_of_tmds == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "out of TMDs");
|
||||
isp->isp_osinfo.out_of_tmds = jiffies;
|
||||
}
|
||||
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__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
isp->isp_osinfo.out_of_tmds = 0;
|
||||
if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) {
|
||||
isp->isp_osinfo.bfreelist = NULL;
|
||||
}
|
||||
@@ -2177,23 +2177,29 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the f/w is out of resources, just send a QUFLL status back.
|
||||
* If the f/w is out of resources, just send a BUSY status back.
|
||||
*/
|
||||
if (aep->at_rxid == AT7_NORESRC_RXID) {
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: Chan %d F/W out of resources for command from 0x%016llxx/0x%06x to lun %u", __FUNCTION__, chan, (unsigned long long)iid, sid, lun);
|
||||
isp_endcmd(isp, aep, nphdl, chan, SCSI_QFULL, 0);
|
||||
isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're out of resources, just send a BUSY status back.
|
||||
*/
|
||||
if ((tmd = isp->isp_osinfo.tfreelist) == NULL || aep->at_rxid == AT7_NORESRC_RXID) {
|
||||
isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] Chan %d out of TMDs for command from 0x%016llxx/0x%06x to lun %u", __FUNCTION__, aep->at_rxid, chan,
|
||||
(unsigned long long)iid, sid, lun);
|
||||
isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0);
|
||||
if ((tmd = isp->isp_osinfo.tfreelist) == NULL) {
|
||||
if (isp->isp_osinfo.out_of_tmds == 0) {
|
||||
isp_prt(isp, ISP_LOGWARN, "out of TMDs");
|
||||
isp->isp_osinfo.out_of_tmds = jiffies;
|
||||
}
|
||||
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__);
|
||||
}
|
||||
return;
|
||||
}
|
||||
isp->isp_osinfo.out_of_tmds = 0;
|
||||
if ((isp->isp_osinfo.tfreelist = tmd->cd_next) == NULL) {
|
||||
isp->isp_osinfo.bfreelist = NULL;
|
||||
}
|
||||
@@ -2286,7 +2292,16 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
|
||||
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);
|
||||
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) {
|
||||
isp->isp_osinfo.bfreelist->cd_next = tmd;
|
||||
} else {
|
||||
isp->isp_osinfo.tfreelist = tmd;
|
||||
}
|
||||
isp->isp_osinfo.bfreelist = tmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4337,7 +4352,7 @@ isplinux_reinit(ispsoftc_t *isp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *file, const int line)
|
||||
{
|
||||
DECLARE_MUTEX_LOCKED(sem);
|
||||
@@ -4349,7 +4364,7 @@ isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *f
|
||||
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;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4361,13 +4376,13 @@ isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *f
|
||||
tap->count++;
|
||||
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "async thread event %d from %s:%d now has count %d", action, file, line, tap->count);
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (isp->isp_osinfo.nt_actions >= MAX_THREAD_ACTION) {
|
||||
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;
|
||||
return (-1);
|
||||
}
|
||||
tap = &isp->isp_osinfo.t_actions[isp->isp_osinfo.nt_actions++];
|
||||
tap->count = 1;
|
||||
@@ -4388,6 +4403,7 @@ isp_thread_event(ispsoftc_t *isp, int action, void *a, int dowait, const char *f
|
||||
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags);
|
||||
isp_prt(isp, ISP_LOGDEBUG1, "action %d from %s:%d sent", action, file, line);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_linux.h,v 1.145 2007/12/05 00:41:42 mjacob Exp $ */
|
||||
/* $Id: isp_linux.h,v 1.146 2007/12/11 22:19:07 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -361,6 +361,7 @@ struct isposinfo {
|
||||
|
||||
u64 cmds_started;
|
||||
u64 cmds_completed;
|
||||
unsigned long out_of_tmds;
|
||||
#endif
|
||||
};
|
||||
#define mbtimer isp_osinfo.mbtimer
|
||||
@@ -678,7 +679,7 @@ void isplinux_undo_proc(ispsoftc_t *);
|
||||
int isplinux_reinit(ispsoftc_t *);
|
||||
void isplinux_sqd(struct Scsi_Host *, struct scsi_device *);
|
||||
|
||||
void isp_thread_event(ispsoftc_t *, int, void *, int, const char *, const int line);
|
||||
int isp_thread_event(ispsoftc_t *, int, void *, int, const char *, const int line);
|
||||
|
||||
static inline uint64_t _isp_microtime_sub(struct timeval *, struct timeval *);
|
||||
static inline void _isp_usec_delay(unsigned int);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: isp_pci.c,v 1.147 2007/12/09 00:08:24 mjacob Exp $ */
|
||||
/* $Id: isp_pci.c,v 1.148 2007/12/11 22:17:34 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -3341,6 +3341,7 @@ isplinux_pci_init(void)
|
||||
}
|
||||
ret = pci_register_driver(&isplinux_pci_driver);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: unable to register driver (return value %d)", __FUNCTION__, ret);
|
||||
unregister_chrdev_region(isp_dev, MAX_ISP);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: scsi_target.c,v 1.75 2007/12/02 22:02:06 mjacob Exp $ */
|
||||
/* $Id: scsi_target.c,v 1.76 2007/12/11 22:16:38 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -413,64 +413,6 @@ static struct file_operations scsi_target_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int
|
||||
scsi_target_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
switch(cmd) {
|
||||
case SC_ENABLE_LUN:
|
||||
case SC_DISABLE_LUN:
|
||||
{
|
||||
sc_enable_t local, *sc = &local;
|
||||
if (COPYIN((void *)arg, (void *)sc, sizeof (*sc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rv = scsi_target_endis(sc->hba_name_unit, sc->nbytes, sc->channel, sc->lun, (cmd == SC_ENABLE_LUN)? ((sc->flags & SC_EF_OVERCOMMIT)? 2 : 1) : 0);
|
||||
break;
|
||||
}
|
||||
case SC_PUT_IO:
|
||||
case SC_GET_IO:
|
||||
{
|
||||
sc_io_t sc;
|
||||
|
||||
if (COPYIN((void *)arg, (void *)&sc, sizeof (sc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (cmd == SC_PUT_IO) {
|
||||
rv = scsi_target_end_user_io(&sc);
|
||||
} else {
|
||||
rv = scsi_target_start_user_io(&sc);
|
||||
}
|
||||
if (COPYOUT((void *)&sc, (void *)arg, sizeof (sc))) {
|
||||
if (rv == 0) {
|
||||
rv = EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SC_DEBUG:
|
||||
{
|
||||
int odebug = scsi_tdebug;
|
||||
if (COPYIN((void *)arg, (void *)&scsi_tdebug, sizeof (int))) {
|
||||
rv = EFAULT;
|
||||
break;
|
||||
}
|
||||
if (COPYOUT((void *)&odebug, (void *)arg, sizeof (int))) {
|
||||
rv = EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
validate_bus_pointer(bus_t *bp, void *identity)
|
||||
{
|
||||
@@ -542,6 +484,107 @@ bus_from_notify(tmd_notify_t *np)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
scsi_target_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
switch(cmd) {
|
||||
case SC_ENABLE_LUN:
|
||||
case SC_DISABLE_LUN:
|
||||
{
|
||||
sc_enable_t local, *sc = &local;
|
||||
if (COPYIN((void *)arg, (void *)sc, sizeof (*sc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
rv = scsi_target_endis(sc->hba_name_unit, sc->nbytes, sc->channel, sc->lun, (cmd == SC_ENABLE_LUN)? ((sc->flags & SC_EF_OVERCOMMIT)? 2 : 1) : 0);
|
||||
break;
|
||||
}
|
||||
case SC_PUT_IO:
|
||||
case SC_GET_IO:
|
||||
{
|
||||
sc_io_t sc;
|
||||
|
||||
if (COPYIN((void *)arg, (void *)&sc, sizeof (sc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
if (cmd == SC_PUT_IO) {
|
||||
rv = scsi_target_end_user_io(&sc);
|
||||
} else {
|
||||
rv = scsi_target_start_user_io(&sc);
|
||||
}
|
||||
if (COPYOUT((void *)&sc, (void *)arg, sizeof (sc))) {
|
||||
if (rv == 0) {
|
||||
rv = EFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SC_DEBUG:
|
||||
{
|
||||
int odebug = scsi_tdebug;
|
||||
if (COPYIN((void *)arg, (void *)&scsi_tdebug, sizeof (int))) {
|
||||
rv = EFAULT;
|
||||
break;
|
||||
}
|
||||
if (COPYOUT((void *)&odebug, (void *)arg, sizeof (int))) {
|
||||
rv = EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SC_INJECT_UA:
|
||||
{
|
||||
sc_inject_ua_t local, *sc = &local;
|
||||
bus_t *bp;
|
||||
struct bus_chan *bc;
|
||||
unsigned long flags;
|
||||
int i, n;
|
||||
|
||||
if (COPYIN((void *)arg, (void *)sc, sizeof (sc))) {
|
||||
rv = -EFAULT;
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&scsi_target_lock, flags);
|
||||
bp = bus_from_name(sc->hba_name_unit);
|
||||
if (bp == NULL) {
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
rv = -ENXIO;
|
||||
break;
|
||||
}
|
||||
for (rv = n = 0; n < bp->h.r_nchannels && rv == 0; n++) {
|
||||
bc = &bp->bchan[n];
|
||||
for (i = 0; i < HASH_WIDTH && rv == 0; i++) {
|
||||
ini_t *ini;
|
||||
for (ini = bc->list[i]; ini; ini = ini->ini_next) {
|
||||
sdata_t *t = sdp;
|
||||
if (t == NULL) {
|
||||
rv = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
sdp = t->next;
|
||||
t->next = NULL;
|
||||
memcpy(t->sdata, ua, sizeof (ua));
|
||||
if (ini->ini_sdata == NULL) {
|
||||
ini->ini_sdata = t;
|
||||
} else {
|
||||
ini->ini_sdata_tail->next = t;
|
||||
}
|
||||
ini->ini_sdata_tail = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rv = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make an initiator structure
|
||||
@@ -1081,8 +1124,14 @@ doit:
|
||||
xact->td_hflags |= TDFH_STSVALID;
|
||||
if (ini && ini->ini_sdata) {
|
||||
memcpy(tmd->cd_sense, ini->ini_sdata->sdata, TMD_SENSELEN);
|
||||
rem_sdata(ini);
|
||||
} else {
|
||||
memset(tmd->cd_sense, 0, TMD_SENSELEN);
|
||||
if (ini == NULL) {
|
||||
printk("%s%d: no initiator structure for sense data\n", bp->h.r_name, bp->h.r_inst);
|
||||
} else {
|
||||
printk("%s%d: no sense data available\n", bp->h.r_name, bp->h.r_inst);
|
||||
}
|
||||
memcpy(tmd->cd_sense, nosense, TMD_SENSELEN);
|
||||
}
|
||||
printk("%s%d: INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u CHECK (0x%x 0x%x 0x%x)\n", bp->h.r_name, bp->h.r_inst, tmd->cd_iid, L0LUN_TO_FLATLUN(tmd->cd_lun),
|
||||
tmd->cd_tagval, tmd->cd_cdb[0] & 0xff, tmd->cd_totlen, tmd->cd_sense[2] & 0xf, tmd->cd_sense[12], tmd->cd_sense[13]);
|
||||
@@ -1827,7 +1876,6 @@ scsi_target_handler(qact_e action, void *arg)
|
||||
{
|
||||
tmd_xact_t *xact = arg;
|
||||
tmd_cmd_t *tmd = xact->td_cmd;
|
||||
ini_t *nptr;
|
||||
|
||||
bp = bus_from_tmd(tmd);
|
||||
if (bp == NULL) {
|
||||
@@ -1895,13 +1943,8 @@ scsi_target_handler(qact_e action, void *arg)
|
||||
* Did we send sense? If so, remove one sense structure.
|
||||
*/
|
||||
if (xact->td_hflags & TDFH_SNSVALID) {
|
||||
if (xact->td_lflags & TDFL_SENTSENSE) {
|
||||
spin_lock_irqsave(&scsi_target_lock, flags);
|
||||
nptr = ini_from_tmd(bp, tmd);
|
||||
spin_unlock_irqrestore(&scsi_target_lock, flags);
|
||||
if (nptr) {
|
||||
rem_sdata(nptr);
|
||||
}
|
||||
if ((xact->td_lflags & TDFL_SENTSENSE) == 0) {
|
||||
printk(KERN_WARNING "%s: oops, lost sense data\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: scsi_target.h,v 1.28 2007/12/02 22:02:07 mjacob Exp $ */
|
||||
/* $Id: scsi_target.h,v 1.29 2007/12/11 22:16:09 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -105,6 +105,15 @@ typedef struct {
|
||||
} sc_io_t;
|
||||
#define SC_GET_IO (_SI | 3)
|
||||
#define SC_PUT_IO (_SI | 4)
|
||||
|
||||
/*
|
||||
* Inject a UNIT ATTENTION error on the next command for this device
|
||||
*/
|
||||
typedef struct {
|
||||
char hba_name_unit[16];
|
||||
} sc_inject_ua_t;
|
||||
#define SC_INJECT_UA (_SI | 21)
|
||||
|
||||
/*
|
||||
* vim:ts=4:sw=4:expandtab
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: scsi_target_ctl.c,v 1.20 2007/12/02 22:02:07 mjacob Exp $ */
|
||||
/* $Id: scsi_target_ctl.c,v 1.21 2007/12/11 22:16:55 mjacob Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1997-2007 by Matthew Jacob
|
||||
* All rights reserved.
|
||||
@@ -76,7 +76,8 @@
|
||||
const char usage[] = "usage: %s\n\
|
||||
scsi_target_ctl debug level\n\
|
||||
scsi_target_ctl enable hba-name-unit channel lun nbytes [ overcommit-file ]\n\
|
||||
scsi_target_ctl disable hba-name-unit channel lun\n";
|
||||
scsi_target_ctl disable hba-name-unit channel lun\n\
|
||||
scsi_target_ctl ua hba-name-unit\n";
|
||||
|
||||
static uint64_t szarg(char *);
|
||||
static void ioloop(int, int, char *, uint16_t);
|
||||
@@ -88,6 +89,7 @@ main(int a, char **v)
|
||||
union {
|
||||
sc_enable_t _x;
|
||||
int _y;
|
||||
sc_inject_ua_t _u;
|
||||
} x;
|
||||
int iofd = -1, fd, action, dd = 0;
|
||||
char *progname;
|
||||
@@ -142,6 +144,12 @@ main(int a, char **v)
|
||||
}
|
||||
action = SC_DEBUG;
|
||||
dd = x._y = atoi(v[2]);
|
||||
} else if (strcmp(v[1], "ua") == 0) {
|
||||
if (a != 3) {
|
||||
goto usage;
|
||||
}
|
||||
strncpy(x._u.hba_name_unit, v[2], sizeof (x._u.hba_name_unit));
|
||||
action = SC_INJECT_UA;
|
||||
} else {
|
||||
goto usage;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user