Merge in work from Feral into this branch. The

recovery from not being able to push a ctio
fix is in. Various task management fixes are
also in. Other work in progress.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@672 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Dotan Barak
2009-02-11 18:55:43 +00:00
parent 5e1547134a
commit 97abf4d107
16 changed files with 2217 additions and 2270 deletions
+227 -355
View File
File diff suppressed because it is too large Load Diff
+21 -22
View File
@@ -1,4 +1,4 @@
/* $Id: isp_library.c,v 1.51 2008/03/10 18:03:08 mjacob Exp $ */
/* $Id: isp_library.c,v 1.55 2009/02/01 23:49:49 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -164,7 +164,7 @@ isp_getrqentry(ispsoftc_t *isp, uint32_t *iptrp,
#define TBA (4 * (((QENTRY_LEN >> 2) * 3) + 1) + 1)
void
isp_print_qentry(ispsoftc_t *isp, char *msg, int idx, void *arg)
isp_print_qentry(ispsoftc_t *isp, const char *msg, int idx, void *arg)
{
char buf[TBA];
int amt, i, j;
@@ -173,9 +173,9 @@ isp_print_qentry(ispsoftc_t *isp, char *msg, int idx, void *arg)
isp_prt(isp, ISP_LOGALL, "%s index %d=>", msg, idx);
for (buf[0] = 0, amt = i = 0; i < 4; i++) {
buf[0] = 0;
SNPRINTF(buf, TBA, " ");
ISP_SNPRINTF(buf, TBA, " ");
for (j = 0; j < (QENTRY_LEN >> 2); j++) {
SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff);
ISP_SNPRINTF(buf, TBA, "%s %02x", buf, ptr[amt++] & 0xff);
}
isp_prt(isp, ISP_LOGALL, buf);
}
@@ -196,7 +196,7 @@ isp_print_bytes(ispsoftc_t *isp, const char *msg, int amt, void *arg)
int j, to;
to = off;
for (j = 0; j < 16; j++) {
SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff);
ISP_SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff);
if (off == amt)
break;
}
@@ -296,14 +296,13 @@ isp_dump_portdb(ispsoftc_t *isp, int chan)
};
fcportdb_t *lp = &fcp->portdb[i];
if (lp->state == FC_PORTDB_STATE_NIL) {
if (lp->state == FC_PORTDB_STATE_NIL && lp->target_mode == 0) {
continue;
}
if (lp->ini_map_idx) {
SNPRINTF(mb, sizeof (mb), "%3d",
((int) lp->ini_map_idx) - 1);
if (lp->dev_map_idx) {
ISP_SNPRINTF(mb, sizeof (mb), "%3d", ((int) lp->dev_map_idx) - 1);
} else {
SNPRINTF(mb, sizeof (mb), "---");
ISP_SNPRINTF(mb, sizeof (mb), "---");
}
isp_prt(isp, ISP_LOGALL, "Chan %d [%d]: hdl 0x%x %s al%d tgt %s"
" %s 0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x",
@@ -1246,7 +1245,7 @@ isp_get_ridacq(ispsoftc_t *isp, isp_ridacq_t *src, isp_ridacq_t *dst)
ISP_IOXGET_8(isp, &src->un.type1.ridacq_vp_status,
dst->un.type1.ridacq_vp_status);
} else {
MEMZERO(&dst->un, sizeof (dst->un));
ISP_MEMZERO(&dst->un, sizeof (dst->un));
}
}
@@ -1392,7 +1391,6 @@ isp_put_sns_request(ispsoftc_t *isp, sns_screq_t *src, sns_screq_t *dst)
for (i = 0; i < nw; i++) {
ISP_IOXPUT_16(isp, src->snscb_data[i], &dst->snscb_data[i]);
}
}
void
@@ -1632,13 +1630,14 @@ isp_get_fc_hdr(ispsoftc_t *isp, fc_hdr_t *src, fc_hdr_t *dst)
ISP_IOZGET_8(isp, &src->s_id[1], dst->s_id[1]);
ISP_IOZGET_8(isp, &src->s_id[2], dst->s_id[2]);
ISP_IOZGET_8(isp, &src->type, dst->type);
ISP_IOZGET_8(isp, &src->f_ctl, dst->f_ctl);
ISP_IOZGET_8(isp, &src->f_ctl[0], dst->f_ctl[0]);
ISP_IOZGET_8(isp, &src->f_ctl[1], dst->f_ctl[1]);
ISP_IOZGET_8(isp, &src->f_ctl[2], dst->f_ctl[2]);
ISP_IOZGET_8(isp, &src->seq_id, dst->seq_id);
ISP_IOZGET_8(isp, &src->df_ctl, dst->df_ctl);
ISP_IOZGET_16(isp, &src->seq_cnt, dst->seq_cnt);
ISP_IOZGET_32(isp, &src->ox_id, dst->parameter);
dst->ox_id = dst->parameter;
dst->rx_id = dst->parameter >> 16;
ISP_IOZGET_16(isp, &src->ox_id, dst->ox_id);
ISP_IOZGET_16(isp, &src->rx_id, dst->rx_id);
ISP_IOZGET_32(isp, &src->parameter, dst->parameter);
}
@@ -2233,7 +2232,7 @@ isp_put_ctio7(ispsoftc_t *isp, ct7_entry_t *src, ct7_entry_t *dst)
ISP_IOXPUT_16(isp, src->ct_nphdl, &dst->ct_nphdl);
ISP_IOXPUT_16(isp, src->ct_timeout, &dst->ct_timeout);
ISP_IOXPUT_16(isp, src->ct_seg_count, &dst->ct_seg_count);
ISP_IOXPUT_8(isp, src->ct_vpindex, &dst->ct_vpindex);
ISP_IOXPUT_8(isp, src->ct_vpidx, &dst->ct_vpidx);
ISP_IOXPUT_8(isp, src->ct_xflags, &dst->ct_xflags);
ISP_IOXPUT_16(isp, src->ct_iid_lo, &dst->ct_iid_lo);
ISP_IOXPUT_8(isp, src->ct_iid_hi, &dst->ct_iid_hi);
@@ -2465,7 +2464,7 @@ isp_get_ctio7(ispsoftc_t *isp, ct7_entry_t *src, ct7_entry_t *dst)
ISP_IOXGET_16(isp, &src->ct_nphdl, dst->ct_nphdl);
ISP_IOXGET_16(isp, &src->ct_timeout, dst->ct_timeout);
ISP_IOXGET_16(isp, &src->ct_seg_count, dst->ct_seg_count);
ISP_IOXGET_8(isp, &src->ct_vpindex, dst->ct_vpindex);
ISP_IOXGET_8(isp, &src->ct_vpidx, dst->ct_vpidx);
ISP_IOXGET_8(isp, &src->ct_xflags, dst->ct_xflags);
ISP_IOXGET_16(isp, &src->ct_iid_lo, dst->ct_iid_lo);
ISP_IOXGET_8(isp, &src->ct_iid_hi, dst->ct_iid_hi);
@@ -2732,7 +2731,7 @@ isp_put_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src,
ISP_IOXPUT_8(isp, src->in_reserved4[i], &dst->in_reserved4[i]);
}
ISP_IOXPUT_8(isp, src->in_reserved5, &dst->in_reserved5);
ISP_IOXPUT_8(isp, src->in_vpindex, &dst->in_vpindex);
ISP_IOXPUT_8(isp, src->in_vpidx, &dst->in_vpidx);
ISP_IOXPUT_32(isp, src->in_reserved6, &dst->in_reserved6);
ISP_IOXPUT_16(isp, src->in_portid_lo, &dst->in_portid_lo);
ISP_IOXPUT_8(isp, src->in_portid_hi, &dst->in_portid_hi);
@@ -2798,7 +2797,7 @@ isp_get_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *src,
ISP_IOXGET_8(isp, &src->in_reserved4[i], dst->in_reserved4[i]);
}
ISP_IOXGET_8(isp, &src->in_reserved5, dst->in_reserved5);
ISP_IOXGET_8(isp, &src->in_vpindex, dst->in_vpindex);
ISP_IOXGET_8(isp, &src->in_vpidx, dst->in_vpidx);
ISP_IOXGET_32(isp, &src->in_reserved6, dst->in_reserved6);
ISP_IOXGET_16(isp, &src->in_portid_lo, dst->in_portid_lo);
ISP_IOXGET_8(isp, &src->in_portid_hi, dst->in_portid_hi);
@@ -2920,7 +2919,7 @@ isp_put_notify_24xx_ack(ispsoftc_t *isp, na_fcentry_24xx_t *src,
ISP_IOXPUT_8(isp, src->na_reserved3[i], &dst->na_reserved3[i]);
}
ISP_IOXPUT_8(isp, src->na_reserved4, &dst->na_reserved4);
ISP_IOXPUT_8(isp, src->na_vpindex, &dst->na_vpindex);
ISP_IOXPUT_8(isp, src->na_vpidx, &dst->na_vpidx);
ISP_IOXPUT_8(isp, src->na_srr_reject_vunique,
&dst->na_srr_reject_vunique);
ISP_IOXPUT_8(isp, src->na_srr_reject_explanation,
@@ -2998,7 +2997,7 @@ isp_get_notify_ack_24xx(ispsoftc_t *isp, na_fcentry_24xx_t *src,
ISP_IOXGET_8(isp, &src->na_reserved3[i], dst->na_reserved3[i]);
}
ISP_IOXGET_8(isp, &src->na_reserved4, dst->na_reserved4);
ISP_IOXGET_8(isp, &src->na_vpindex, dst->na_vpindex);
ISP_IOXGET_8(isp, &src->na_vpidx, dst->na_vpidx);
ISP_IOXGET_8(isp, &src->na_srr_reject_vunique,
dst->na_srr_reject_vunique);
ISP_IOXGET_8(isp, &src->na_srr_reject_explanation,
+13 -13
View File
@@ -1,18 +1,18 @@
/* $Id: isp_library.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */
/* $Id: isp_library.h,v 1.29 2009/01/24 17:55:53 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -24,32 +24,32 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*
*
* Alternatively, this software may be distributed under the terms of the
* the GNU Public License ("GPL") with platforms where the prevalant license
* is the GNU Public License:
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of The Version 2 GNU General Public License as published
* by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*
*
* Matthew Jacob
* Feral Software
* 421 Laurel Avenue
* Menlo Park, CA 94025
* USA
*
*
* gplbsd at feral com
*/
#ifndef _ISP_LIBRARY_H
@@ -63,7 +63,7 @@ uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
uint32_t isp_handle_index(uint32_t);
void isp_destroy_handle(ispsoftc_t *, uint32_t);
int isp_getrqentry(ispsoftc_t *, uint32_t *, uint32_t *, void **);
void isp_print_qentry (ispsoftc_t *, char *, int, void *);
void isp_print_qentry (ispsoftc_t *, const char *, int, void *);
void isp_print_bytes(ispsoftc_t *, const char *, int, void *);
int isp_fc_runstate(ispsoftc_t *, int, int);
void isp_dump_portdb(ispsoftc_t *, int);
+13 -13
View File
@@ -1,18 +1,18 @@
/* $Id: isp_stds.h,v 1.14 2008/02/11 23:59:06 mjacob Exp $ */
/* $Id: isp_stds.h,v 1.15 2008/11/13 22:30:00 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -24,32 +24,32 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*
*
* Alternatively, this software may be distributed under the terms of the
* the GNU Public License ("GPL") with platforms where the prevalant license
* is the GNU Public License:
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of The Version 2 GNU General Public License as published
* by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*
*
* Matthew Jacob
* Feral Software
* 421 Laurel Avenue
* Menlo Park, CA 94025
* USA
*
*
* gplbsd at feral com
*/
/*
@@ -70,7 +70,7 @@ typedef struct {
uint8_t cs_ctl;
uint8_t s_id[3];
uint8_t type;
uint8_t f_ctl;
uint8_t f_ctl[3];
uint8_t seq_id;
uint8_t df_ctl;
uint16_t seq_cnt;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+21 -66
View File
@@ -1,18 +1,18 @@
/* $Id: isp_tpublic.h,v 1.43 2008/04/15 22:40:52 mjacob Exp $ */
/* $Id: isp_tpublic.h,v 1.44 2008/12/03 18:35:05 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -24,32 +24,32 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*
*
* Alternatively, this software may be distributed under the terms of the
* the GNU Public License ("GPL") with platforms where the prevalant license
* is the GNU Public License:
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of The Version 2 GNU General Public License as
* published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*
*
* Matthew Jacob
* Feral Software
* 421 Laurel Avenue
* Menlo Park, CA 94025
* USA
*
*
* gplbsd at feral com
*/
/*
@@ -71,6 +71,10 @@
#ifndef _ISP_TPUBLIC_H
#define _ISP_TPUBLIC_H 1
/*
* Include general target definitions
*/
#include "isp_target.h"
/*
* Action codes set by the Inner Layer for the outer layer to figure out what to do with.
@@ -81,7 +85,7 @@ typedef enum {
QOUT_DISABLE, /* the argument is a pointer to a enadis_t */
QOUT_TMD_START, /* the argument is a pointer to a tmd_cmd_t */
QOUT_TMD_DONE, /* the argument is a pointer to a tmd_xact_t */
QOUT_NOTIFY, /* the argument is a pointer to a tmd_notify_t */
QOUT_NOTIFY, /* the argument is a pointer to a isp_notify_t */
QOUT_HBA_UNREG /* the argument is a pointer to a hba_register_t */
} tact_e;
@@ -98,7 +102,7 @@ typedef enum {
QIN_DISABLE, /* the argument is a pointer to a enadis_t */
QIN_TMD_CONT, /* the argument is a pointer to a tmd_xact_t */
QIN_TMD_FIN, /* the argument is a pointer to a tmd_cmd_t */
QIN_NOTIFY_ACK, /* the argument is a pointer to a tmd_notify_t */
QIN_NOTIFY_ACK, /* the argument is a pointer to a isp_notify_t */
QIN_HBA_UNREG, /* the argument is a pointer to a hba_register_t */
} qact_e;
@@ -160,57 +164,6 @@ typedef struct {
uint64_t * d_wwpns;
} fc_dlist_t;
/*
* Notify structure- these are for asynchronous events that need to be sent
* as notifications to the outer layer. It should be pretty self-explanatory.
*/
typedef enum {
NT_UNKNOWN=0x999,
NT_ABORT_TASK=0x1000,
NT_ABORT_TASK_SET,
NT_CLEAR_ACA,
NT_CLEAR_TASK_SET,
NT_LUN_RESET,
NT_TARGET_RESET,
NT_BUS_RESET,
NT_LIP_RESET,
NT_LINK_UP,
NT_LINK_DOWN,
NT_LOGOUT,
NT_HBA_RESET
} tmd_ncode_t;
typedef struct tmd_notify {
void * nt_hba; /* HBA tag */
uint64_t nt_iid; /* inititator id */
uint64_t nt_tgt; /* target id */
uint16_t nt_lun; /* logical unit */
uint16_t : 15,
nt_need_ack : 1; /* this notify needs an ACK */
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;
#define LUN_ANY 0xffff
#define TGT_ANY ((uint64_t) -1)
#ifdef INI_ANY
#define INI_ANY ((uint64_t) -1)
#endif
#ifndef INI_NONE
#define INI_NONE ((uint64_t) 0)
#endif
#define TAG_ANY ((uint64_t) 0)
#define MATCH_TMD(tmd, iid, lun, tag) \
( \
(tmd) && \
(iid == INI_ANY || iid == tmd->cd_iid) && \
(lun == LUN_ANY || lun == tmd->cd_lun) && \
(tag == TAG_ANY || tag == tmd->cd_tagval) \
)
/*
* Lun ENABLE/DISABLE
*
@@ -290,6 +243,7 @@ typedef struct tmd_xact {
#define TDFL_SENTSTATUS 0x01 /* this transaction sent status */
#define TDFL_SENTSENSE 0x02 /* this transaction sent sense data */
#define TDFL_ERROR 0x04 /* this transaction had an error */
#define TDFL_SYNCERROR 0x08 /* ... and didn't even start because of it */
#define TDFL_PRIVATE 0xF0 /* private inner layer usage */
/*
@@ -349,7 +303,7 @@ typedef struct tmd_xact {
* The cd_xact tag is the first or only transaction structure related to this command.
*
* The tag cd_lreserved, cd_hreserved are scratch areas for use for the outer and inner layers respectively.
*
*
*/
#ifndef TMD_CDBLEN
@@ -441,6 +395,7 @@ struct tmd_cmd {
*
* void scsi_target_handler(tact_e, void *arg)
*/
#endif /* _ISP_TPUBLIC_H */
/*
* vim:ts=4:sw=4:expandtab
+929 -22
View File
File diff suppressed because it is too large Load Diff
+26 -15
View File
@@ -1,18 +1,18 @@
/* $Id: ispreg.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */
/* $Id: ispreg.h,v 1.30 2009/01/24 17:55:53 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -24,32 +24,32 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
*
*
* Alternatively, this software may be distributed under the terms of the
* the GNU Public License ("GPL") with platforms where the prevalant license
* is the GNU Public License:
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of The Version 2 GNU General Public License as published
* by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*
*
* Matthew Jacob
* Feral Software
* 421 Laurel Avenue
* Menlo Park, CA 94025
* USA
*
*
* gplbsd at feral com
*/
/*
@@ -374,7 +374,7 @@
/*
* 2400 Interface Offsets and Register Definitions
*
*
* The 2400 looks quite different in terms of registers from other QLogic cards.
* It is getting to be a genuine pain and challenge to keep the same model
* for all.
@@ -476,7 +476,7 @@
#define OUTMAILBOX7 (MBOX_BLOCK+0xE)
/*
* Strictly speaking, it's
* Strictly speaking, it's
* SCSI && 2100 : 8 MBOX registers
* 2200: 24 MBOX registers
* 2300/2400: 32 MBOX registers
@@ -497,10 +497,21 @@ typedef struct {
uint16_t param[MAILBOX_STORAGE];
uint16_t ibits;
uint16_t obits;
uint32_t : 28,
uint32_t
lineno : 16,
: 12,
logval : 4;
uint32_t timeout;
const char *func;
} mbreg_t;
#define MBSINIT(mbxp, code, loglev, timo) \
ISP_MEMZERO((mbxp), sizeof (mbreg_t)); \
(mbxp)->param[0] = code; \
(mbxp)->lineno = __LINE__; \
(mbxp)->func = __func__; \
(mbxp)->logval = loglev; \
(mbxp)->timeout = timo
/*
* Fibre Protocol Module and Frame Buffer Register Offsets/Definitions (2X00).
+74 -17
View File
@@ -1,4 +1,4 @@
/* $Id: ispvar.h,v 1.99 2008/06/16 23:53:18 mjacob Exp $ */
/* $Id: ispvar.h,v 1.103 2009/02/01 23:49:49 mjacob Exp $ */
/*-
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -292,9 +292,8 @@ typedef struct {
/*
* Special Constants
*/
#define INI_NONE ((uint64_t) 0)
#define INI_ANY ((uint64_t) -1)
#define VALID_INI(ini) (ini != INI_NONE && ini != INI_ANY)
#define INI_NONE ((uint64_t) 0)
#define ISP_NOCHAN 0xff
/*
* Special Port IDs
@@ -317,11 +316,11 @@ typedef struct {
*
* It has a state. If the state if VALID, that means that we've logged into
* the device. We also *may* have a initiator map index entry. This is a value
* from 0..MAX_FC_TARG that is used to index into the isp_ini_map array. If
* from 0..MAX_FC_TARG that is used to index into the isp_dev_map array. If
* the value therein is non-zero, then that value minus one is used to index
* into the Port Database to find the handle for forming commands. There is
* back-index minus one value within to Port Database entry that tells us
* which entry in isp_ini_map points to us (to avoid searching).
* which entry in isp_dev_map points to us (to avoid searching).
*
* Local loop devices the firmware automatically performs PLOGI on for us
* (which is why that handle is imposed upon us). Fabric devices we assign
@@ -354,7 +353,7 @@ typedef struct {
*
* + There can never be two non-NIL entries with the same handle.
*
* + There can never be two non-NIL entries which have the same ini_map_idx
* + There can never be two non-NIL entries which have the same dev_map_idx
* value.
*/
typedef struct {
@@ -366,8 +365,8 @@ typedef struct {
uint16_t handle;
/*
* The ini_map_idx, if nonzero, is the system virtual target ID (+1)
* as a cross-reference with the isp_ini_map.
* The dev_map_idx, if nonzero, is the system virtual target ID (+1)
* as a cross-reference with the isp_dev_map.
*
* A device is 'autologin' if the firmware automatically logs into
* it (re-logins as needed). Basically, local private loop devices.
@@ -381,10 +380,10 @@ typedef struct {
*
* The 'target_mode' tag means that this entry arrived via a
* target mode command and is immune from normal flushing rules.
* You should also never see anything with no initiator role
* You should also never see anything with an initiator role
* with this set.
*/
uint16_t ini_map_idx : 12,
uint16_t dev_map_idx : 12,
autologin : 1, /* F/W does PLOGI/PLOGO */
state : 3;
uint32_t reserved : 5,
@@ -464,7 +463,7 @@ typedef struct {
* subtract one to get the portdb index. This means that
* entries which are zero are unmapped (i.e., don't exist).
*/
uint16_t isp_ini_map[MAX_FC_TARG];
uint16_t isp_dev_map[MAX_FC_TARG];
/*
* Scratch DMA mapped in area to fetch Port Database stuff, etc.
@@ -571,6 +570,7 @@ struct ispsoftc {
volatile uint32_t isp_resodx; /* index of next result */
volatile uint32_t isp_lasthdls; /* last handle seed */
volatile uint32_t isp_obits; /* mailbox command output */
volatile uint32_t isp_serno; /* rolling serial number */
volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE];
volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */
volatile uint16_t isp_mbxwrk0;
@@ -937,11 +937,11 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
*
* ISP_FC_SCRLEN FC scratch area DMA length
*
* MEMZERO(dst, src) platform zeroing function
* MEMCPY(dst, src, count) platform copying function
* SNPRINTF(buf, bufsize, fmt, ...) snprintf
* USEC_DELAY(usecs) microsecond spindelay function
* USEC_SLEEP(isp, usecs) microsecond sleep function
* ISP_MEMZERO(dst, src) platform zeroing function
* ISP_MEMCPY(dst, src, count) platform copying function
* ISP_SNPRINTF(buf, bufsize, fmt, ...) snprintf
* ISP_DELAY(usecs) microsecond spindelay function
* ISP_SLEEP(isp, usecs) microsecond sleep function
*
* NANOTIME_T nanosecond time type
*
@@ -1051,4 +1051,61 @@ void isp_async(ispsoftc_t *, ispasync_t, ...);
* ISP_SWAP32(ispsoftc_t *, uint32_t srcval)
*/
#ifdef ISP_TARGET_MODE
/*
* The functions below are for the publicly available
* target mode functions that are internal to the Qlogic driver.
*/
/*
* This function handles new response queue entry appropriate for target mode.
*/
int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
/*
* This function externalizes the ability to acknowledge an Immediate Notify request.
*/
int isp_notify_ack(ispsoftc_t *, void *);
/*
* This function externalized acknowledging (success/fail) an ABTS frame
*/
int isp_acknak_abts(ispsoftc_t *, void *, int);
/*
* Enable/Disable/Modify a logical unit.
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt)
*/
#define DFLT_CMND_CNT 0xfe /* unmonitored */
#define DFLT_INOT_CNT 0xfe /* unmonitored */
int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int);
/*
* General request queue 'put' routine for target mode entries.
*/
int isp_target_put_entry(ispsoftc_t *isp, void *);
/*
* General routine to put back an ATIO entry-
* used for replenishing f/w resource counts.
* The argument is a pointer to a source ATIO
* or ATIO2.
*/
int isp_target_put_atio(ispsoftc_t *, void *);
/*
* General routine to send a final CTIO for a command- used mostly for
* local responses.
*/
int isp_endcmd(ispsoftc_t *, ...);
#define ECMD_SVALID 0x100
#define ECMD_TERMINATE 0x200
/*
* Handle an asynchronous event
*
* Return nonzero if the interrupt that generated this event has been dismissed.
*/
int isp_target_async(ispsoftc_t *, int, int);
#endif
#endif /* _ISPVAR_H */
+9 -8
View File
@@ -1,4 +1,4 @@
/* $Id: isp_cb_ops.c,v 1.95 2008/09/12 20:53:44 mjacob Exp $ */
/* $Id: isp_cb_ops.c,v 1.98 2009/02/01 23:49:55 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -198,7 +198,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
io = len;
} else if (strncmp(buf, "bins", 4) == 0) {
ISP_LOCKU_SOFTC(isp);
MEMZERO(isp->isp_osinfo.bins, sizeof (isp->isp_osinfo.bins));
memset(isp->isp_osinfo.bins, 0, sizeof (isp->isp_osinfo.bins));
ISP_UNLKU_SOFTC(isp);
io = len;
}
@@ -296,10 +296,10 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) {
continue;
}
if (fcp->portdb[i].ini_map_idx) {
if (fcp->portdb[i].dev_map_idx) {
copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s (target %d)\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n",
i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles],
fcp->portdb[i].ini_map_idx - 1, (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn);
fcp->portdb[i].dev_map_idx - 1, (ull) fcp->portdb[i].port_wwn, (ull) fcp->portdb[i].node_wwn);
} else {
copy_info(&info, "\tdbidx %d handle 0x%x PortID 0x%06x role %s\n\tPort WWN 0x%016llx Node WWN 0x%016llx\n\n",
i, fcp->portdb[i].handle, fcp->portdb[i].portid, isp_class3_roles[fcp->portdb[i].roles],
@@ -422,7 +422,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
{
isp_stats_t stats;
MEMZERO(&stats, sizeof stats);
memset(&stats, 0, sizeof stats);
stats.isp_stat_version = ISP_STATS_VERSION;
stats.isp_type = isp->isp_type;
stats.isp_revision = isp->isp_revision;
@@ -642,7 +642,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
break;
}
MEMZERO(&mbs, sizeof (mbs));
memset(&mbs, 0, sizeof (mbs));
needmarker = 0;
loopid = fct->loopid;
if (ISP_CAP_2KLOGIN(isp) == 0) {
@@ -771,7 +771,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd)
uint8_t local[QENTRY_LEN];
ispreq_t *reqp;
int time, result = 0;
DECLARE_MUTEX_LOCKED(rsem);
struct semaphore rsem;
unsigned long flags;
time = cmd->timeout / 1000;
@@ -781,7 +781,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd)
if (IS_24XX(isp) && time > 0x1999) {
time = 0x1999;
}
MEMZERO(local, sizeof (local));
memset(local, 0, sizeof (local));
Cmnd = isp_kzalloc(sizeof (struct scsi_cmnd), GFP_KERNEL);
if (Cmnd == NULL) {
result = -ENOMEM;
@@ -797,6 +797,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd)
dev->host = host;
Cmnd->scsi_done = isp_run_cmd_done;
Cmnd->SCp.ptr = (char *)&rsem;
sema_init(&rsem, 0);
ISP_LOCKU_SOFTC(isp);
if (isp_getrqentry(isp, &nxti, &optr, (void *)&reqp)) {
+1 -1
View File
@@ -1,4 +1,4 @@
/* $Id: isp_ioctl.h,v 1.28 2008/02/11 23:59:06 mjacob Exp $ */
/* $Id: isp_ioctl.h,v 1.29 2008/09/12 22:24:31 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
+310 -282
View File
File diff suppressed because it is too large Load Diff
+32 -46
View File
@@ -1,4 +1,4 @@
/* $Id: isp_linux.h,v 1.164 2008/08/20 15:50:56 mjacob Exp $ */
/* $Id: isp_linux.h,v 1.168 2009/01/24 17:55:55 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -245,7 +245,7 @@ typedef uint8_t isp_bmap_t;
#define N_NOTIFIES 256
#define DEFAULT_INQSIZE 32
typedef struct isp_notify isp_notify_t;
typedef struct notify notify_t;
#define cd_action cd_lreserved[0].shorts[0]
#define cd_oxid cd_lreserved[0].shorts[1]
@@ -327,8 +327,8 @@ struct isposinfo {
u16 wqhiwater;
u16 hiwater;
struct timer_list timer;
struct timer_list mbtimer;
struct semaphore mbox_sem;
wait_queue_head_t mboxwq;
struct semaphore mbox_c_sem;
spinlock_t slock;
unsigned volatile int
@@ -338,7 +338,6 @@ struct isposinfo {
: 1,
dogactive : 1,
mboxcmd_done : 1,
mbox_waiting : 1,
mbintsok : 1,
intsok : 1;
u16 frame_size;
@@ -362,9 +361,9 @@ struct isposinfo {
struct tmd_cmd * tfreelist; /* freelist head */
struct tmd_cmd * bfreelist; /* freelist tail */
struct tmd_cmd * pool; /* pool itself */
isp_notify_t * pending_n; /* pending list of notifies going upstream */
isp_notify_t * nfreelist; /* freelist */
isp_notify_t * npool; /* pool itself */
notify_t * pending_n; /* pending list of notifies going upstream */
notify_t * nfreelist; /* freelist */
notify_t * npool; /* pool itself */
struct tmd_xact * pending_x; /* pending list of xacts going upstream */
/*
* When we have inquiry commands that we have to xfer data with
@@ -382,8 +381,6 @@ struct isposinfo {
};
#define mbtimer isp_osinfo.mbtimer
#define dogactive isp_osinfo.dogactive
#define mbox_sem isp_osinfo.mbox_sem
#define mbox_c_sem isp_osinfo.mbox_c_sem
#define mbintsok isp_osinfo.mbintsok
#define intsok isp_osinfo.intsok
#define mbox_waiting isp_osinfo.mbox_waiting
@@ -410,9 +407,7 @@ struct isposinfo {
#define ISP_DRIVER_CTL_ENTRY_LOCK(isp) do { } while (0)
#define ISP_DRIVER_CTL_EXIT_LOCK(isp) do { } while (0)
#define ISP_ATOMIC in_atomic
#define ISP_MUST_POLL(isp) (ISP_ATOMIC() || isp->mbintsok == 0)
#define ISP_MUST_POLL(isp) (in_interrupt() || isp->mbintsok == 0)
/*
* Required Macros/Defines
@@ -424,11 +419,11 @@ struct isposinfo {
#define ISP_FC_SCRLEN 0x1000
#define MEMZERO(b, a) memset(b, 0, a)
#define MEMCPY memcpy
#define SNPRINTF snprintf
#define USEC_DELAY _isp_usec_delay
#define USEC_SLEEP(isp, x) \
#define ISP_MEMZERO(b, a) memset(b, 0, a)
#define ISP_MEMCPY memcpy
#define ISP_SNPRINTF snprintf
#define ISP_DELAY _isp_usec_delay
#define ISP_SLEEP(isp, x) \
ISP_DROP_LK_SOFTC(isp); \
__set_current_state(TASK_UNINTERRUPTIBLE); \
(void) schedule_timeout(_usec_to_jiffies(x)); \
@@ -452,15 +447,12 @@ struct isposinfo {
# endif
#endif
#define MBOX_ACQUIRE(isp) down_trylock(&isp->mbox_sem)
#define MBOX_ACQUIRE(isp) down_trylock(&isp->isp_osinfo.mbox_sem)
#define MBOX_WAIT_COMPLETE mbox_wait_complete
#define MBOX_NOTIFY_COMPLETE(isp) \
if (isp->mbox_waiting) { \
isp->mbox_waiting = 0; \
up(&isp->mbox_c_sem); \
} \
#define MBOX_NOTIFY_COMPLETE(isp) \
wake_up(&isp->isp_osinfo.mboxwq); \
isp->mboxcmd_done = 1
#define MBOX_RELEASE(isp) up(&isp->mbox_sem)
#define MBOX_RELEASE(isp) up(&isp->isp_osinfo.mbox_sem)
#define FC_SCRATCH_ACQUIRE fc_scratch_acquire
#define FC_SCRATCH_RELEASE(isp, chan) ISP_DATA(isp, chan)->scratch_busy = 0
@@ -540,7 +532,7 @@ struct isposinfo {
#define XS_INITERR(xs) (xs)->result = 0, (xs)->SCp.Status = 0
#define XS_SAVE_SENSE(Cmnd, s, l) MEMCPY(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l))
#define XS_SAVE_SENSE(Cmnd, s, l) memcpy(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l))
#define XS_SET_STATE_STAT(a, b, c)
@@ -617,14 +609,12 @@ typedef struct {
uint64_t def_wwpn;
uint32_t
tgts_tested : 16,
: 10,
fcrswdog : 1,
: 1,
: 11,
scratch_busy : 1,
blocked : 1,
deadloop : 1,
role : 2;
unsigned long downcount;
unsigned long downcount, nextscan;
unsigned int qfdelay;
} isp_data;
@@ -818,7 +808,7 @@ static inline void
mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
{
uint32_t lim = mbp->timeout;
unsigned long long tt = jiffies;
unsigned long long et, tt = jiffies;
if (lim == 0) {
lim = MBCMD_DEFAULT_TIMEOUT;
@@ -843,7 +833,13 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
break;
}
}
ISP_ENABLE_INTS(isp);
ISP_DROP_LK_SOFTC(isp);
udelay(100);
ISP_IGET_LK_SOFTC(isp);
if (isp->mboxcmd_done) {
break;
}
}
if (isp->mboxcmd_done == 0) {
isp_prt(isp, ISP_LOGWARN, "Polled Mailbox Command (0x%x) Timeout (%llu elapsed jiffies)", isp->isp_lastmbxcmd, ((unsigned long long) jiffies) - tt);
@@ -851,26 +847,16 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
}
} else {
isp_prt(isp, ISP_LOGDEBUG1, "Start Interrupting Mailbox Command (%x)", isp->isp_lastmbxcmd);
init_timer(&isp->mbtimer);
isp->mbtimer.data = (unsigned long) isp;
isp->mbtimer.function = isplinux_mbtimer;
isp->mbtimer.expires = tt;
isp->mbtimer.expires += ((lim/1000000) * HZ);
isp->mbtimer.expires += ((lim%1000000) / HZ);
add_timer(&isp->mbtimer);
isp->mbox_waiting = 1;
ISP_ENABLE_INTS(isp);
ISP_DROP_LK_SOFTC(isp);
down(&isp->mbox_c_sem);
et = wait_event_timeout(isp->isp_osinfo.mboxwq, isp->mboxcmd_done, usecs_to_jiffies(lim));
ISP_IGET_LK_SOFTC(isp);
isp->mbox_waiting = 0;
del_timer(&isp->mbtimer);
if (isp->mboxcmd_done == 0) {
if (et == 0) {
isp_prt(isp, ISP_LOGWARN, "Interrupting Mailbox Command (0x%x) Timeout (elapsed time %llu jiffies)", isp->isp_lastmbxcmd,
((unsigned long long) jiffies) - tt);
mbp->param[0] = MBOX_TIMEOUT;
} else {
isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%llu jiffies)", isp->isp_lastmbxcmd, ((unsigned long long) jiffies) - tt);
isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%llu jiffies)", isp->isp_lastmbxcmd, et);
}
}
}
@@ -919,7 +905,7 @@ isp_kzalloc(size_t size, int flags)
{
void *ptr = isp_kalloc(size, flags);
if (ptr != NULL){
MEMZERO(ptr, size);
memset(ptr, 0, size);
}
return (ptr);
}
@@ -945,8 +931,8 @@ int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
int isp_enable_lun(ispsoftc_t *, uint16_t, uint16_t);
int isp_disable_lun(ispsoftc_t *, uint16_t, uint16_t);
struct isp_notify {
tmd_notify_t notify;
struct notify {
isp_notify_t notify;
uint8_t qentry[QENTRY_LEN]; /* original immediate notify entry */
uint8_t qevalid;
};
+58 -70
View File
@@ -1,4 +1,4 @@
/* $Id: isp_pci.c,v 1.172 2008/08/20 15:50:56 mjacob Exp $ */
/* $Id: isp_pci.c,v 1.175 2009/01/24 17:55:55 mjacob Exp $ */
/*
* Copyright (c) 1997-2008 by Matthew Jacob
* All rights reserved.
@@ -549,6 +549,9 @@ isplinux_pci_init_one(struct Scsi_Host *host)
isp->isp_dblev = isp_debug;
} else {
isp->isp_dblev = ISP_LOGCONFIG|ISP_LOGINFO|ISP_LOGWARN|ISP_LOGERR;
#ifdef ISP_TARGET_MODE
isp->isp_dblev |= ISP_LOGTINFO;
#endif
}
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
@@ -1484,7 +1487,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "ATIO Queue not on 64 byte boundary");
goto bad;
}
MEMZERO(isp->isp_atioq, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
memset(isp->isp_atioq, 0, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
}
#endif
if (isp->isp_rquest == NULL) {
@@ -1499,7 +1502,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "Request Queue not on 64 byte boundary");
goto bad;
}
MEMZERO(isp->isp_rquest, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
memset(isp->isp_rquest, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
}
if (isp->isp_result == NULL) {
@@ -1514,7 +1517,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "Result Queue not on 64 byte boundary");
goto bad;
}
MEMZERO(isp->isp_result, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
memset(isp->isp_result, 0, ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp)));
}
if (IS_FC(isp)) {
@@ -1528,7 +1531,7 @@ isp_pci_mbxdma(ispsoftc_t *isp)
goto bad;
}
fcp->isp_scdma = busaddr;
MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
memset(fcp->isp_scratch, 0, ISP_FC_SCRLEN);
if (fcp->isp_scdma & 0x7) {
isp_prt(isp, ISP_LOGERR, "scratch space not 8 byte aligned");
goto bad;
@@ -1583,11 +1586,6 @@ bad:
static int tdma_mk(ispsoftc_t *, tmd_xact_t *, ct_entry_t *, uint32_t *, uint32_t);
static int tdma_mkfc(ispsoftc_t *, tmd_xact_t *, ct2_entry_t *, uint32_t *, uint32_t);
#define ALLOW_SYNTHETIC_CTIO 1
#ifndef ALLOW_SYNTHETIC_CTIO
#define cto2 0
#endif
#define STATUS_WITH_DATA 1
/*
@@ -1642,7 +1640,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin
cto->ct_xfrlen = 0;
cto->ct_seg_count = 0;
cto->ct_header.rqs_entry_count = 1;
MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg));
memset(cto->ct_dataseg, 0, sizeof (cto->ct_dataseg));
if (xact->td_xfrlen == 0) {
ISP_TDQE(isp, "tdma_mk[no data]", curi, cto);
@@ -1859,7 +1857,7 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin
cto->ct_xfrlen = 0;
cto->ct_resid = 0;
cto->ct_seg_count = 0;
MEMZERO(cto->ct_dataseg, sizeof (cto->ct_dataseg));
memset(cto->ct_dataseg, 0, sizeof (cto->ct_dataseg));
}
}
*nxtip = nxti;
@@ -1913,8 +1911,16 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
uint32_t bc, last_synthetic_count;
long xfcnt; /* must be signed */
int nseg, seg, ovseg, seglim, new_seg_cnt;
#ifdef ALLOW_SYNTHETIC_CTIO
ct7_entry_t *cto2 = NULL, ct2;
#if 0
{
static int fred = 0;
if (fred++ == 100) {
fred = 0;
printk("YAGGA!\n");
return (CMD_EAGAIN);
}
}
#endif
nxti = *nxtip;
@@ -1991,7 +1997,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
if (new_seg_cnt == 0) {
isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__);
cto->ct_resid = -ENOMEM;
cto->ct_resid = -EFAULT;
return (CMD_COMPLETE);
}
tmd->cd_nseg = new_seg_cnt;
@@ -2011,12 +2017,11 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
swd = cto->ct_scsi_status;
if ((cto->ct_flags & CT7_SENDSTATUS) && ((swd & 0xff) || cto->ct_resid)) {
#ifdef ALLOW_SYNTHETIC_CTIO
cto2 = &ct2;
/*
* Copy over CTIO2
*/
MEMCPY(cto2, cto, sizeof (ct7_entry_t));
memcpy(cto2, cto, sizeof (ct7_entry_t));
/*
* Clear fields from first CTIO7 that now need to be cleared
@@ -2032,18 +2037,13 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
cto2->ct_flags &= ~(CT7_FLAG_MMASK|CT7_DATAMASK);
cto2->ct_flags |= CT7_NO_DATA|CT7_NO_DATA|CT7_FLAG_MODE1;
cto2->ct_seg_count = 0;
MEMZERO(&cto2->rsp, sizeof (cto2->rsp));
memset(&cto2->rsp, 0, sizeof (cto2->rsp));
cto2->ct_scsi_status = swd;
if ((swd & 0xff) == SCSI_CHECK && (xact->td_hflags & TDFH_SNSVALID)) {
cto2->rsp.m1.ct_resplen = min(TMD_SENSELEN, MAXRESPLEN_24XX);
MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_resplen);
memcpy(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_resplen);
cto2->ct_scsi_status |= (FCP_SNSLEN_VALID << 8);
}
#else
cto->ct_flags &= ~CT7_SENDSTATUS;
cto->ct_resid = 0;
cto->ct_scsi_status = 0;
#endif
}
/*
@@ -2074,8 +2074,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
last_synthetic_addr = addr;
} else {
cto->rsp.m0.ds.ds_count = bc;
isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __func__, seg,
(unsigned long)cto->rsp.m0.ds.ds_basehi, (unsigned long)cto->rsp.m0.ds.ds_base, bc);
isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg%d[%d]%llx:%u", __func__, 0, 0, (unsigned long long) addr, bc);
}
cto->rsp.m0.ct_xfrlen += bc;
xfcnt -= bc;
@@ -2092,10 +2091,10 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
do {
int lim;
uint32_t curip;
ispcontreq_t local, *crq = &local, *qep;
ispcontreq64_t local, *crq = &local, *qep;
curip = nxti;
qep = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip);
qep = (ispcontreq64_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, curip);
nxti = ISP_NXT_QENTRY((curip), RQUEST_QUEUE_LEN(isp));
if (nxti == optr) {
pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
@@ -2103,13 +2102,13 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
return (CMD_EAGAIN);
}
cto->ct_header.rqs_entry_count++;
MEMZERO((void *)crq, sizeof (*crq));
BUG_ON(cto->ct_header.rqs_entry_count == 0);
memset((void *)crq, 0, sizeof (*crq));
crq->req_header.rqs_entry_count = 1;
crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
lim = ISP_CDSEG64;
for (ovseg = 0; (seg < nseg || last_synthetic_count) && ovseg < lim; seg++, ovseg++, sg++) {
ispcontreq64_t *xrq;
if (last_synthetic_count) {
addr = last_synthetic_addr;
bc = last_synthetic_count;
@@ -2125,19 +2124,18 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
cto->ct_seg_count++;
cto->rsp.m0.ct_xfrlen += bc;
xrq = (ispcontreq64_t *) crq;
xrq->req_dataseg[ovseg].ds_count = bc;
xrq->req_dataseg[ovseg].ds_base = LOWD(addr);
xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
crq->req_dataseg[ovseg].ds_count = bc;
crq->req_dataseg[ovseg].ds_base = LOWD(addr);
crq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
/*
* Make sure we don't cross a 4GB boundary.
*/
if (!SAME_4G(addr, bc)) {
isp_prt(isp, ISP_LOGTDEBUG1, "seg%d[%d]%llx:%u (TRUNC'd)", cto->ct_header.rqs_entry_count-1, ovseg, (long long)addr, bc);
xrq->req_dataseg[ovseg].ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr);
addr += xrq->req_dataseg[ovseg].ds_count;
bc -= xrq->req_dataseg[ovseg].ds_count;
xfcnt -= xrq->req_dataseg[ovseg].ds_count;
crq->req_dataseg[ovseg].ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr);
addr += crq->req_dataseg[ovseg].ds_count;
bc -= crq->req_dataseg[ovseg].ds_count;
xfcnt -= crq->req_dataseg[ovseg].ds_count;
/*
* Do we have space to split it here?
*/
@@ -2147,26 +2145,21 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
cto->ct_seg_count++;
} else {
ovseg++;
xrq->req_dataseg[ovseg].ds_count = bc;
xrq->req_dataseg[ovseg].ds_base = LOWD(addr);
xrq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
crq->req_dataseg[ovseg].ds_count = bc;
crq->req_dataseg[ovseg].ds_base = LOWD(addr);
crq->req_dataseg[ovseg].ds_basehi = HIWD(addr);
}
}
}
ISP_TDQE(isp, "tdma_mk_2400 cont", curip, crq);
MEMORYBARRIER(isp, SYNC_REQUEST, curip, QENTRY_LEN);
if (crq->req_header.rqs_entry_type == RQSTYPE_A64_CONT) {
isp_put_cont64_req(isp, (ispcontreq64_t *)crq, (ispcontreq64_t *)qep);
} else {
isp_put_cont_req(isp, crq, qep);
}
isp_put_cont64_req(isp, (ispcontreq64_t *)crq, (ispcontreq64_t *)qep);
} while (seg < nseg || last_synthetic_count);
isp_prt(isp, ISP_LOGTDEBUG2, "[%llx]: map %d segments at %p for handle 0x%x", tmd->cd_tagval, new_seg_cnt, xact->td_data, cto->ct_syshandle);
mbxsync:
#ifdef ALLOW_SYNTHETIC_CTIO
/*
* If we have a final CTIO2, allocate and push *that*
* onto the request queue.
@@ -2178,14 +2171,12 @@ mbxsync:
if (nxti == optr) {
pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT7_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__);
cto->ct_resid = -EAGAIN;
return (CMD_COMPLETE);
return (CMD_EAGAIN);
}
MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
isp_put_ctio7(isp, cto2, (ct7_entry_t *)qe);
ISP_TDQE(isp, "tdma_mk_2400:final", curi, cto2);
}
#endif
qe = ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
isp_put_ctio7(isp, cto, qe);
if (cto->ct_flags & CT2_FASTPOST) {
@@ -2212,9 +2203,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
uint32_t bc, last_synthetic_count;
long xfcnt; /* must be signed */
int nseg, seg, ovseg, seglim, new_seg_cnt;
#ifdef ALLOW_SYNTHETIC_CTIO
ct2_entry_t *cto2 = NULL, ct2;
#endif
nxti = *nxtip;
curi = isp->isp_reqidx;
@@ -2257,7 +2246,11 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
/* ct_syshandle contains the synchronization handle set by caller */
cto->ct_seg_count = 0;
cto->ct_reloff = 0;
isp_put_ctio2(isp, cto, qe);
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe);
} else {
isp_put_ctio2(isp, cto, qe);
}
if (cto->ct_flags & CT2_FASTPOST) {
isp_prt(isp, ISP_LOGTDEBUG1, "[%x] faspost (0x%x)", cto->ct_rxid, tmd->cd_cdb[0]);
}
@@ -2312,7 +2305,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
new_seg_cnt = pci_map_sg(pcs->pci_dev, sg, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
if (new_seg_cnt == 0) {
isp_prt(isp, ISP_LOGWARN, "%s: unable to dma map request", __func__);
cto->ct_resid = -ENOMEM;
cto->ct_resid = -EFAULT;
return (CMD_COMPLETE);
}
tmd->cd_nseg = new_seg_cnt;
@@ -2322,12 +2315,11 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
*/
if ((cto->ct_flags & CT2_SENDSTATUS) && ((swd & 0xff) || cto->ct_resid)) {
#ifdef ALLOW_SYNTHETIC_CTIO
cto2 = &ct2;
/*
* Copy over CTIO2
*/
MEMCPY(cto2, cto, sizeof (ct2_entry_t));
memcpy(cto2, cto, sizeof (ct2_entry_t));
/*
* Clear fields from first CTIO2 that now need to be cleared
@@ -2344,10 +2336,10 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
cto2->ct_flags |= CT2_NO_DATA|CT2_FLAG_MODE1;
cto2->ct_seg_count = 0;
cto2->ct_reloff = 0;
MEMZERO(&cto2->rsp, sizeof (cto2->rsp));
memset(&cto2->rsp, 0, sizeof (cto2->rsp));
if ((swd & 0xff) == SCSI_CHECK && (swd & CT2_SNSLEN_VALID)) {
cto2->rsp.m1.ct_senselen = min(TMD_SENSELEN, MAXRESPLEN);
MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_senselen);
memcpy(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_senselen);
swd |= CT2_SNSLEN_VALID;
}
if (cto2->ct_resid > 0) {
@@ -2359,11 +2351,6 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
if (cto2->ct_flags & CT2_CCINCR) {
tmd->cd_lflags &= ~CDFL_RESRC_FILL;
}
#else
cto->ct_flags &= ~(CT2_SENDSTATUS|CT2_CCINCR|CT2_FASTPOST);
cto->ct_resid = 0;
cto->rsp.m0.ct_scsi_status = 0;
#endif
} else if ((cto->ct_flags & (CT2_SENDSTATUS|CT2_CCINCR)) == (CT2_SENDSTATUS|CT2_CCINCR)) {
tmd->cd_lflags &= ~CDFL_RESRC_FILL;
}
@@ -2487,7 +2474,7 @@ again:
return (CMD_EAGAIN);
}
cto->ct_header.rqs_entry_count++;
MEMZERO((void *)crq, sizeof (*crq));
memset((void *)crq, 0, sizeof (*crq));
crq->req_header.rqs_entry_count = 1;
if (cto->ct_header.rqs_entry_type == RQSTYPE_CTIO3) {
crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
@@ -2582,7 +2569,6 @@ again:
mbxsync:
#ifdef ALLOW_SYNTHETIC_CTIO
/*
* If we have a final CTIO2, allocate and push *that*
* onto the request queue.
@@ -2594,16 +2580,18 @@ mbxsync:
if (nxti == optr) {
pci_unmap_sg(pcs->pci_dev, xact->td_data, nseg, (cto->ct_flags & CT2_DATA_IN)? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
isp_prt(isp, ISP_LOGTDEBUG0, "%s: request queue overflow", __func__);
cto->ct_resid = -EAGAIN;
return (CMD_COMPLETE);
return (CMD_EAGAIN);
}
MEMORYBARRIER(isp, SYNC_REQUEST, curi, QENTRY_LEN);
isp_put_ctio2(isp, cto2, (ct2_entry_t *)qe);
ISP_TDQE(isp, "tdma_mkfc:final", curi, cto2);
}
#endif
qe = ISP_QUEUE_ENTRY(isp->isp_rquest, isp->isp_reqidx);
isp_put_ctio2(isp, cto, qe);
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_ctio2e(isp, (ct2e_entry_t *)cto, (ct2e_entry_t *)qe);
} else {
isp_put_ctio2(isp, cto, qe);
}
if (cto->ct_flags & CT2_FASTPOST) {
isp_prt(isp, ISP_LOGTDEBUG1, "[%x] fastpost (0x%x) with entry count %d", cto->ct_rxid, tmd->cd_cdb[0], cto->ct_header.rqs_entry_count);
}
@@ -2871,7 +2859,7 @@ again:
return (CMD_EAGAIN);
}
rq->req_header.rqs_entry_count++;
MEMZERO((void *)crq, sizeof (*crq));
memset((void *)crq, 0, sizeof (*crq));
crq->req_header.rqs_entry_count = 1;
if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS || rq->req_header.rqs_entry_type == RQSTYPE_A64) {
crq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
@@ -3135,7 +3123,7 @@ isp_pci_2400_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, ispreq_t *orig_rq, uint3
return (CMD_EAGAIN);
}
rq->req_header.rqs_entry_count++;
MEMZERO((void *)xrq, sizeof (*xrq));
memset((void *)xrq, 0, sizeof (*xrq));
xrq->req_header.rqs_entry_count = 1;
xrq->req_header.rqs_entry_type = RQSTYPE_A64_CONT;
lim = ISP_CDSEG64;
+58 -43
View File
@@ -243,7 +243,7 @@ bus_from_name(const char *name)
}
static __inline bus_t *
bus_from_notify(tmd_notify_t *np)
bus_from_notify(isp_notify_t *np)
{
bus_t *bp;
for (bp = busses; bp < &busses[MAX_BUS]; bp++) {
@@ -430,8 +430,8 @@ rx_loop:
spin_unlock_irq(&bc->tmds_lock);
tmd->cd_scsi_status = SCSI_BUSY;
xact = &tmd->cd_xact;
xact->td_hflags |= TDFH_STSVALID;
xact->td_hflags &= ~TDFH_DATA_MASK;
xact->td_hflags = TDFH_STSVALID;
xact->td_lflags = 0;
xact->td_xfrlen = 0;
(*bp->h.r_action)(QIN_TMD_CONT, xact);
goto rx_loop;
@@ -578,8 +578,8 @@ bus_chan_add_initiators(bus_t *bp, int chan)
tmd->cd_scsi_status = SCSI_BUSY;
xact = &tmd->cd_xact;
xact->td_hflags |= TDFH_STSVALID;
xact->td_hflags &= ~TDFH_DATA_MASK;
xact->td_hflags = TDFH_STSVALID;
xact->td_lflags = 0;
xact->td_xfrlen = 0;
(*bp->h.r_action)(QIN_TMD_CONT, xact);
@@ -714,7 +714,7 @@ abort_all_tasks(bus_chan_t *bc, uint64_t iid)
}
static void
scsi_target_notify(tmd_notify_t *np)
scsi_target_notify(isp_notify_t *np)
{
bus_t *bp;
bus_chan_t *bc;
@@ -725,14 +725,6 @@ scsi_target_notify(tmd_notify_t *np)
uint8_t lunbuf[8];
unsigned long flags;
/*
* XXX If task management fail we can't give info to isp driver via tpublic
* XXX notifies interface. FC stuff is capable to handle errors in TM.
* XXX But TM is rare and TM errors are even more rare, so we can ignore errors
* XXX now. Maybe tpublic API change, than we could uncomment passing errors to
* XXX low level driver.
*/
spin_lock_irqsave(&scsi_target_lock, flags);
bp = bus_from_notify(np);
if (unlikely(bp == NULL || bp->bchan == NULL)) {
@@ -742,13 +734,12 @@ scsi_target_notify(tmd_notify_t *np)
}
spin_unlock_irqrestore(&scsi_target_lock, flags);
SDprintk("scsi_target: MGT code %x from %s%d iid 0x%016llx tag %llx\n",
np->nt_ncode, bp->h.r_name, bp->h.r_inst, np->nt_iid, np->nt_tagval);
SDprintk("scsi_target: MGT code %x from %s%d iid 0x%016llx tag %llx\n", np->nt_ncode, bp->h.r_name, bp->h.r_inst, np->nt_wwn, np->nt_tagval);
bc = &bp->bchan[np->nt_channel];
spin_lock_irqsave(&bc->tmds_lock, flags);
ini = ini_from_iid(bc, np->nt_iid);
ini = ini_from_iid(bc, np->nt_wwn);
np->nt_ini = ini;
__ini_get(np->nt_ini);
spin_unlock_irqrestore(&bc->tmds_lock, flags);
@@ -759,12 +750,12 @@ scsi_target_notify(tmd_notify_t *np)
if (ini == NULL) {
goto err_no_ini;
}
if (abort_task(bc, np->nt_iid, np->nt_tagval)) {
if (abort_task(bc, np->nt_wwn, np->nt_tagval)) {
SDprintk("TMD_NOTIFY abort task [%llx]\n", np->nt_tagval);
goto notify_ack;
}
if (scst_rx_mgmt_fn_tag(ini->ini_scst_sess, SCST_ABORT_TASK, np->nt_tagval, 1, np) < 0) {
//np->nt_error = NT_FAILED;
np->nt_failed = 1;
goto notify_ack;
}
/* wait for SCST now */
@@ -774,7 +765,7 @@ scsi_target_notify(tmd_notify_t *np)
if (ini == NULL) {
goto err_no_ini;
}
abort_all_tasks(bc, np->nt_iid);
abort_all_tasks(bc, np->nt_wwn);
fn = SCST_ABORT_TASK_SET;
break;
case NT_CLEAR_TASK_SET:
@@ -782,7 +773,7 @@ scsi_target_notify(tmd_notify_t *np)
if (ini == NULL) {
goto err_no_ini;
}
abort_all_tasks(bc, np->nt_iid);
abort_all_tasks(bc, np->nt_wwn);
fn = SCST_CLEAR_TASK_SET;
break;
case NT_CLEAR_ACA:
@@ -792,7 +783,7 @@ scsi_target_notify(tmd_notify_t *np)
case NT_LUN_RESET:
tmf = "LUN RESET";
if (np->nt_lun == LUN_ANY) {
//np->nt_error = NT_REJECT;
np->nt_failed = 1;
goto notify_ack;
}
fn = SCST_LUN_RESET;
@@ -813,14 +804,16 @@ scsi_target_notify(tmd_notify_t *np)
goto notify_ack;
case NT_LOGOUT:
spin_lock_irqsave(&bc->tmds_lock, flags);
/* If someone disable target during this notify, reference to initiator
/*
* If someone disables the target during this notify, reference to initiator
* is currently dropped, so we need to check if IID is still in initiators
* table to avoid double free */
if (del_ini(bc, np->nt_iid)) {
SDprintk("droping reference to initiator 0x%016llx\n", np->nt_iid);
* table to avoid double free
*/
if (del_ini(bc, np->nt_wwn)) {
SDprintk("droping reference to initiator 0x%016llx\n", np->nt_wwn);
__ini_put(bc, ini);
} else {
Eprintk("cannot logout initiator 0x%016llx\n", np->nt_iid);
Eprintk("cannot logout initiator 0x%016llx\n", np->nt_wwn);
}
spin_unlock_irqrestore(&bc->tmds_lock, flags);
goto notify_ack;
@@ -841,15 +834,15 @@ scsi_target_notify(tmd_notify_t *np)
}
FLATLUN_TO_L0LUN(lunbuf, lun);
if (scst_rx_mgmt_fn_lun(ini->ini_scst_sess, fn, lunbuf, sizeof(lunbuf), 1, np) < 0) {
//np->nt_error = NT_FAILED;
np->nt_failed = 1;
goto notify_ack;
}
}
return;
err_no_ini:
Eprintk("cannot find initiator 0x%016llx for %s\n", np->nt_iid, tmf);
//np->nt_error = NT_REJECT;
Eprintk("cannot find initiator 0x%016llx for %s\n", np->nt_wwn, tmf);
np->nt_failed = 1;
notify_ack:
ini_put(bc, ini);
(*bp->h.r_action) (QIN_NOTIFY_ACK, np);
@@ -922,7 +915,7 @@ scsi_target_handler(qact_e action, void *arg)
}
case QOUT_NOTIFY:
{
tmd_notify_t *np = arg;
isp_notify_t *np = arg;
SDprintk("scsi_target: TMD_NOTIFY %p code=0x%x\n", np, np->nt_ncode);
scsi_target_notify(np);
break;
@@ -1089,7 +1082,8 @@ isp_rdy_to_xfer(struct scst_cmd *scst_cmd)
bus_chan_t *bc = &bp->bchan[tmd->cd_channel];
int len = scst_cmd_get_bufflen(scst_cmd);
xact->td_hflags |= TDFH_DATA_OUT;
xact->td_hflags = TDFH_DATA_OUT;
xact->td_lflags = 0;
xact->td_data = scst_cmd_get_sg(scst_cmd);
xact->td_xfrlen = len;
if (bp->h.r_type == R_SPI) {
@@ -1109,15 +1103,24 @@ isp_rdy_to_xfer(struct scst_cmd *scst_cmd)
SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel);
up_read(&bc->disable_sem);
scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR, SCST_CONTEXT_SAME);
return (0);
return (SCST_TGT_RES_SUCCESS);
}
SDprintk2("%s: TMD[%llx] write nbytes %u\n", __FUNCTION__, tmd->cd_tagval, scst_cmd_get_bufflen(scst_cmd));
(*bp->h.r_action)(QIN_TMD_CONT, xact);
up_read(&bc->disable_sem);
(*bp->h.r_action)(QIN_TMD_CONT, xact);
/*
* Did we have an error starting this particular transaction?
*/
if (unlikely(xact->td_lflags & (TDFL_ERROR|TDFL_SYNCERROR)) == (TDFL_ERROR|TDFL_SYNCERROR)) {
if (xact->td_error == -ENOMEM) {
return (SCST_TGT_RES_QUEUE_FULL);
} else {
return (SCST_TGT_RES_FATAL_ERROR);
}
}
}
return (0);
return (SCST_TGT_RES_SUCCESS);
}
static int
@@ -1131,7 +1134,7 @@ isp_xmit_response(struct scst_cmd *scst_cmd)
if (unlikely(scst_cmd_aborted(scst_cmd))) {
scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED);
scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
return (0);
return (SCST_TGT_RES_SUCCESS);
}
if (scst_cmd_get_data_direction(scst_cmd) == SCST_DATA_READ) {
@@ -1147,11 +1150,11 @@ isp_xmit_response(struct scst_cmd *scst_cmd)
Eprintk("data size too big (totlen %u len %u)\n", tmd->cd_totlen, len);
memcpy(tmd->cd_sense, ifailure, TMD_SENSELEN);
xact->td_hflags |= TDFH_STSVALID;
xact->td_hflags = TDFH_STSVALID;
tmd->cd_scsi_status = SCSI_CHECK;
goto out;
} else {
xact->td_hflags |= TDFH_DATA_IN;
xact->td_hflags = TDFH_DATA_IN;
xact->td_xfrlen = len;
xact->td_data = scst_cmd_get_sg(scst_cmd);
}
@@ -1161,6 +1164,8 @@ isp_xmit_response(struct scst_cmd *scst_cmd)
xact->td_hflags &= ~TDFH_DATA_MASK;
}
xact->td_lflags = 0;
if (scst_cmd_get_is_send_status(scst_cmd)) {
xact->td_hflags |= TDFH_STSVALID;
tmd->cd_scsi_status = scst_cmd_get_status(scst_cmd);
@@ -1208,14 +1213,24 @@ out:
SDprintk("%s: TMD[%llx] Chan %d not enabled\n", __FUNCTION__, tmd->cd_tagval, tmd->cd_channel);
up_read(&bc->disable_sem);
scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME);
return (0);
return (SCST_TGT_RES_SUCCESS);
}
SDprintk2("%s: TMD[%llx] %p hf %x lf %x xfrlen %d totlen %d moved %d\n",
__FUNCTION__, tmd->cd_tagval, tmd, xact->td_hflags, xact->td_lflags, xact->td_xfrlen, tmd->cd_totlen, tmd->cd_moved);
(*bp->h.r_action)(QIN_TMD_CONT, xact);
up_read(&bc->disable_sem);
return (0);
(*bp->h.r_action)(QIN_TMD_CONT, xact);
/*
* Did we have an error starting this particular transaction?
*/
if (unlikely(xact->td_lflags & (TDFL_ERROR|TDFL_SYNCERROR)) == (TDFL_ERROR|TDFL_SYNCERROR)) {
if (xact->td_error == -ENOMEM) {
return (SCST_TGT_RES_QUEUE_FULL);
} else {
return (SCST_TGT_RES_FATAL_ERROR);
}
}
return (SCST_TGT_RES_SUCCESS);
}
static void
@@ -1234,7 +1249,7 @@ isp_on_free_cmd(struct scst_cmd *scst_cmd)
static void
isp_task_mgmt_fn_done(struct scst_mgmt_cmd *mgmt_cmd)
{
tmd_notify_t *np = mgmt_cmd->tgt_priv;
isp_notify_t *np = mgmt_cmd->tgt_priv;
bus_t *bp = bus_from_notify(np);
ini_put(&bp->bchan[np->nt_channel], np->nt_ini);