Synchronize with Feral CVS repository:

Go for the gusto and merge multichan_development into the head branch. This
will break FreeBSD and NetBSD ports for a while (yawn) and solaris is dubious
anyway.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@260 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Stanislaw Gruszka
2008-02-12 09:18:28 +00:00
parent 75428f7e2d
commit 698091ebcb
20 changed files with 16524 additions and 13741 deletions
+1290 -1040
View File
File diff suppressed because it is too large Load Diff
+212 -36
View File
@@ -1,4 +1,4 @@
/* $Id: isp_library.c,v 1.46 2007/10/29 18:12:33 mjacob Exp $ */
/* $Id: isp_library.c,v 1.47 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -75,6 +75,10 @@ __FBSDID("$FreeBSD$");
#include "isp_solaris.h"
#endif
const char *isp_class3_roles[4] = {
"None", "Target", "Initiator", "Target/Initiator"
};
int
isp_save_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep)
{
@@ -214,50 +218,53 @@ isp_print_bytes(ispsoftc_t *isp, const char *msg, int amt, void *arg)
*/
int
isp_fc_runstate(ispsoftc_t *isp, int tval)
isp_fc_runstate(ispsoftc_t *isp, int chan, int tval)
{
fcparam *fcp;
int *tptr;
if (isp->isp_role == ISP_ROLE_NONE) {
fcp = FCPARAM(isp, chan);
if (fcp->role == ISP_ROLE_NONE) {
return (0);
}
fcp = FCPARAM(isp);
tptr = &tval;
if (fcp->isp_fwstate < FW_READY ||
fcp->isp_loopstate < LOOP_PDB_RCVD) {
if (isp_control(isp, ISPCTL_FCLINK_TEST, tptr) != 0) {
if (isp_control(isp, ISPCTL_FCLINK_TEST, chan, tval) != 0) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: linktest failed");
"isp_fc_runstate: linktest failed for channel %d",
chan);
return (-1);
}
if (fcp->isp_fwstate != FW_READY ||
fcp->isp_loopstate < LOOP_PDB_RCVD) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: f/w not ready");
"isp_fc_runstate: f/w not ready for channel %d",
chan);
return (-1);
}
}
if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {
if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
return (0);
}
if (isp_control(isp, ISPCTL_SCAN_LOOP, NULL) != 0) {
if (isp_control(isp, ISPCTL_SCAN_LOOP, chan) != 0) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: scan loop fails");
"isp_fc_runstate: scan loop fails on channel %d", chan);
return (LOOP_PDB_RCVD);
}
if (isp_control(isp, ISPCTL_SCAN_FABRIC, NULL) != 0) {
if (isp_control(isp, ISPCTL_SCAN_FABRIC, chan) != 0) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: scan fabric fails");
"isp_fc_runstate: scan fabric fails on channel %d", chan);
return (LOOP_LSCAN_DONE);
}
if (isp_control(isp, ISPCTL_PDB_SYNC, NULL) != 0) {
isp_prt(isp, ISP_LOGSANCFG, "isp_fc_runstate: pdb_sync fails");
if (isp_control(isp, ISPCTL_PDB_SYNC, chan) != 0) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: pdb_sync fails on channel %d", chan);
return (LOOP_FSCAN_DONE);
}
if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
isp_prt(isp, ISP_LOGSANCFG,
"isp_fc_runstate: f/w not ready again");
"isp_fc_runstate: f/w not ready again on channel %d", chan);
return (-1);
}
return (0);
@@ -267,9 +274,9 @@ isp_fc_runstate(ispsoftc_t *isp, int tval)
* Fibre Channel Support- get the port database for the id.
*/
void
isp_dump_portdb(ispsoftc_t *isp)
isp_dump_portdb(ispsoftc_t *isp, int chan)
{
fcparam *fcp = (fcparam *) isp->isp_param;
fcparam *fcp = FCPARAM(isp, chan);
int i;
for (i = 0; i < MAX_FC_TARG; i++) {
@@ -298,9 +305,9 @@ isp_dump_portdb(ispsoftc_t *isp)
} else {
SNPRINTF(mb, sizeof (mb), "---");
}
isp_prt(isp, ISP_LOGALL, "%d: hdl 0x%x %s al%d tgt %s %s "
"0x%06x =>%s 0x%06x; WWNN 0x%08x%08x WWPN 0x%08x%08x", i,
lp->handle, dbs[lp->state], lp->autologin, 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",
chan, i, lp->handle, dbs[lp->state], lp->autologin, mb,
roles[lp->roles], lp->portid,
roles[lp->new_roles], lp->new_portid,
(uint32_t) (lp->node_wwn >> 32),
@@ -906,6 +913,138 @@ isp_put_icb_2400(ispsoftc_t *isp, isp_icb_2400_t *src, isp_icb_2400_t *dst)
}
}
void
isp_put_icb_2400_vpinfo(ispsoftc_t *isp, isp_icb_2400_vpinfo_t *src, isp_icb_2400_vpinfo_t *dst)
{
ISP_IOXPUT_16(isp, src->vp_count, &dst->vp_count);
ISP_IOXPUT_16(isp, src->vp_global_options, &dst->vp_global_options);
}
void
isp_put_vp_port_info(ispsoftc_t *isp, vp_port_info_t *src, vp_port_info_t *dst)
{
int i;
ISP_IOXPUT_16(isp, src->vp_port_status, &dst->vp_port_status);
ISP_IOXPUT_8(isp, src->vp_port_options, &dst->vp_port_options);
ISP_IOXPUT_8(isp, src->vp_port_loopid, &dst->vp_port_loopid);
for (i = 0; i < 8; i++) {
ISP_IOXPUT_8(isp, src->vp_port_portname[i], &dst->vp_port_portname[i]);
}
for (i = 0; i < 8; i++) {
ISP_IOXPUT_8(isp, src->vp_port_nodename[i], &dst->vp_port_nodename[i]);
}
/* we never *put* portid_lo/portid_hi */
}
void
isp_get_vp_port_info(ispsoftc_t *isp, vp_port_info_t *src, vp_port_info_t *dst)
{
int i;
ISP_IOXGET_16(isp, &src->vp_port_status, dst->vp_port_status);
ISP_IOXGET_8(isp, &src->vp_port_options, dst->vp_port_options);
ISP_IOXGET_8(isp, &src->vp_port_loopid, dst->vp_port_loopid);
for (i = 0; i < ASIZE(src->vp_port_portname); i++) {
ISP_IOXGET_8(isp, &src->vp_port_portname[i], dst->vp_port_portname[i]);
}
for (i = 0; i < ASIZE(src->vp_port_nodename); i++) {
ISP_IOXGET_8(isp, &src->vp_port_nodename[i], dst->vp_port_nodename[i]);
}
ISP_IOXGET_16(isp, &src->vp_port_portid_lo, dst->vp_port_portid_lo);
ISP_IOXGET_16(isp, &src->vp_port_portid_hi, dst->vp_port_portid_hi);
}
void
isp_put_vp_ctrl_info(ispsoftc_t *isp, vp_ctrl_info_t *src, vp_ctrl_info_t *dst)
{
int i;
isp_put_hdr(isp, &src->vp_ctrl_hdr, &dst->vp_ctrl_hdr);
ISP_IOXPUT_32(isp, src->vp_ctrl_handle, &dst->vp_ctrl_handle);
ISP_IOXPUT_16(isp, src->vp_ctrl_index_fail, &dst->vp_ctrl_index_fail);
ISP_IOXPUT_16(isp, src->vp_ctrl_status, &dst->vp_ctrl_status);
ISP_IOXPUT_16(isp, src->vp_ctrl_command, &dst->vp_ctrl_command);
ISP_IOXPUT_16(isp, src->vp_ctrl_vp_count, &dst->vp_ctrl_vp_count);
for (i = 0; i < ASIZE(src->vp_ctrl_idmap); i++) {
ISP_IOXPUT_16(isp, src->vp_ctrl_idmap[i], &dst->vp_ctrl_idmap[i]);
}
for (i = 0; i < ASIZE(src->vp_ctrl_reserved); i++) {
ISP_IOXPUT_8(isp, src->vp_ctrl_idmap[i], &dst->vp_ctrl_idmap[i]);
}
}
void
isp_get_vp_ctrl_info(ispsoftc_t *isp, vp_ctrl_info_t *src, vp_ctrl_info_t *dst)
{
int i;
isp_get_hdr(isp, &src->vp_ctrl_hdr, &dst->vp_ctrl_hdr);
ISP_IOXGET_32(isp, &src->vp_ctrl_handle, dst->vp_ctrl_handle);
ISP_IOXGET_16(isp, &src->vp_ctrl_index_fail, dst->vp_ctrl_index_fail);
ISP_IOXGET_16(isp, &src->vp_ctrl_status, dst->vp_ctrl_status);
ISP_IOXGET_16(isp, &src->vp_ctrl_command, dst->vp_ctrl_command);
ISP_IOXGET_16(isp, &src->vp_ctrl_vp_count, dst->vp_ctrl_vp_count);
for (i = 0; i < ASIZE(src->vp_ctrl_idmap); i++) {
ISP_IOXGET_16(isp, &src->vp_ctrl_idmap[i], dst->vp_ctrl_idmap[i]);
}
for (i = 0; i < ASIZE(src->vp_ctrl_reserved); i++) {
ISP_IOXGET_8(isp, &src->vp_ctrl_reserved[i], dst->vp_ctrl_reserved[i]);
}
}
void
isp_put_vp_modify(ispsoftc_t *isp, vp_modify_t *src, vp_modify_t *dst)
{
int i, j;
isp_put_hdr(isp, &src->vp_mod_hdr, &dst->vp_mod_hdr);
ISP_IOXPUT_32(isp, src->vp_mod_hdl, &dst->vp_mod_hdl);
ISP_IOXPUT_16(isp, src->vp_mod_reserved0, &dst->vp_mod_reserved0);
ISP_IOXPUT_16(isp, src->vp_mod_status, &dst->vp_mod_status);
ISP_IOXPUT_8(isp, src->vp_mod_cmd, &dst->vp_mod_cmd);
ISP_IOXPUT_8(isp, src->vp_mod_cnt, &dst->vp_mod_cnt);
ISP_IOXPUT_8(isp, src->vp_mod_idx0, &dst->vp_mod_idx0);
ISP_IOXPUT_8(isp, src->vp_mod_idx1, &dst->vp_mod_idx1);
for (i = 0; i < ASIZE(src->vp_mod_ports); i++) {
ISP_IOXPUT_8(isp, src->vp_mod_ports[i].options, &dst->vp_mod_ports[i].options);
ISP_IOXPUT_8(isp, src->vp_mod_ports[i].loopid, &dst->vp_mod_ports[i].loopid);
ISP_IOXPUT_16(isp, src->vp_mod_ports[i].reserved1, &dst->vp_mod_ports[i].reserved1);
for (j = 0; j < ASIZE(src->vp_mod_ports[i].wwpn); j++) {
ISP_IOXPUT_8(isp, src->vp_mod_ports[i].wwpn[j], &dst->vp_mod_ports[i].wwpn[j]);
}
for (j = 0; j < ASIZE(src->vp_mod_ports[i].wwnn); j++) {
ISP_IOXPUT_8(isp, src->vp_mod_ports[i].wwnn[j], &dst->vp_mod_ports[i].wwnn[j]);
}
}
for (i = 0; i < ASIZE(src->vp_mod_reserved2); i++) {
ISP_IOXPUT_8(isp, src->vp_mod_reserved2[i], &dst->vp_mod_reserved2[i]);
}
}
void
isp_get_vp_modify(ispsoftc_t *isp, vp_modify_t *src, vp_modify_t *dst)
{
int i, j;
isp_get_hdr(isp, &src->vp_mod_hdr, &dst->vp_mod_hdr);
ISP_IOXGET_32(isp, &src->vp_mod_hdl, dst->vp_mod_hdl);
ISP_IOXGET_16(isp, &src->vp_mod_reserved0, dst->vp_mod_reserved0);
ISP_IOXGET_16(isp, &src->vp_mod_status, dst->vp_mod_status);
ISP_IOXGET_8(isp, &src->vp_mod_cmd, dst->vp_mod_cmd);
ISP_IOXGET_8(isp, &src->vp_mod_cnt, dst->vp_mod_cnt);
ISP_IOXGET_8(isp, &src->vp_mod_idx0, dst->vp_mod_idx0);
ISP_IOXGET_8(isp, &src->vp_mod_idx1, dst->vp_mod_idx1);
for (i = 0; i < ASIZE(src->vp_mod_ports); i++) {
ISP_IOXGET_8(isp, &src->vp_mod_ports[i].options, dst->vp_mod_ports[i].options);
ISP_IOXGET_8(isp, &src->vp_mod_ports[i].loopid, dst->vp_mod_ports[i].loopid);
ISP_IOXGET_16(isp, &src->vp_mod_ports[i].reserved1, dst->vp_mod_ports[i].reserved1);
for (j = 0; j < ASIZE(src->vp_mod_ports[i].wwpn); j++) {
ISP_IOXGET_8(isp, &src->vp_mod_ports[i].wwpn[j], dst->vp_mod_ports[i].wwpn[j]);
}
for (j = 0; j < ASIZE(src->vp_mod_ports[i].wwnn); j++) {
ISP_IOXGET_8(isp, &src->vp_mod_ports[i].wwnn[j], dst->vp_mod_ports[i].wwnn[j]);
}
}
for (i = 0; i < ASIZE(src->vp_mod_reserved2); i++) {
ISP_IOXGET_8(isp, &src->vp_mod_reserved2[i], dst->vp_mod_reserved2[i]);
}
}
void
isp_get_pdb_21xx(ispsoftc_t *isp, isp_pdb_21xx_t *src, isp_pdb_21xx_t *dst)
{
@@ -1037,6 +1176,47 @@ isp_put_plogx(ispsoftc_t *isp, isp_plogx_t *src, isp_plogx_t *dst)
}
}
/*
* Report ID canonicalization
*/
void
isp_get_ridacq(ispsoftc_t *isp, isp_ridacq_t *src, isp_ridacq_t *dst)
{
int i;
isp_get_hdr(isp, &src->ridacq_hdr, &dst->ridacq_hdr);
ISP_IOXGET_32(isp, &src->ridacq_handle, dst->ridacq_handle);
ISP_IOXGET_16(isp, &src->ridacq_vp_port_lo, dst->ridacq_vp_port_lo);
ISP_IOXGET_8(isp, &src->ridacq_vp_port_hi, dst->ridacq_vp_port_hi);
ISP_IOXGET_8(isp, &src->ridacq_format, dst->ridacq_format);
for (i = 0; i < sizeof (src->ridacq_map) / sizeof (src->ridacq_map[0]);
i++) {
ISP_IOXGET_16(isp, &src->ridacq_map[i], dst->ridacq_map[i]);
}
for (i = 0; i < sizeof (src->ridacq_reserved1) /
sizeof (src->ridacq_reserved1[0]); i++) {
ISP_IOXGET_16(isp, &src->ridacq_reserved1[i],
dst->ridacq_reserved1[i]);
}
if (dst->ridacq_format == 0) {
ISP_IOXGET_8(isp, &src->un.type0.ridacq_vp_acquired,
dst->un.type0.ridacq_vp_acquired);
ISP_IOXGET_8(isp, &src->un.type0.ridacq_vp_setup,
dst->un.type0.ridacq_vp_setup);
ISP_IOXGET_16(isp, &src->un.type0.ridacq_reserved0,
dst->un.type0.ridacq_reserved0);
} else if (dst->ridacq_format == 1) {
ISP_IOXGET_16(isp, &src->un.type1.ridacq_vp_count,
dst->un.type1.ridacq_vp_count);
ISP_IOXGET_8(isp, &src->un.type1.ridacq_vp_index,
dst->un.type1.ridacq_vp_index);
ISP_IOXGET_8(isp, &src->un.type1.ridacq_vp_status,
dst->un.type1.ridacq_vp_status);
} else {
MEMZERO(&dst->un, sizeof (dst->un));
}
}
/*
* CT Passthru canonicalization
*/
@@ -1050,13 +1230,14 @@ isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *src, isp_ct_pt_t *dst)
ISP_IOXGET_16(isp, &src->ctp_status, dst->ctp_status);
ISP_IOXGET_16(isp, &src->ctp_nphdl, dst->ctp_nphdl);
ISP_IOXGET_16(isp, &src->ctp_cmd_cnt, dst->ctp_cmd_cnt);
ISP_IOXGET_16(isp, &src->ctp_vpidx, dst->ctp_vpidx);
ISP_IOXGET_8(isp, &src->ctp_vpidx, dst->ctp_vpidx);
ISP_IOXGET_8(isp, &src->ctp_reserved0, dst->ctp_reserved0);
ISP_IOXGET_16(isp, &src->ctp_time, dst->ctp_time);
ISP_IOXGET_16(isp, &src->ctp_reserved0, dst->ctp_reserved0);
ISP_IOXGET_16(isp, &src->ctp_reserved1, dst->ctp_reserved1);
ISP_IOXGET_16(isp, &src->ctp_rsp_cnt, dst->ctp_rsp_cnt);
for (i = 0; i < 5; i++) {
ISP_IOXGET_16(isp, &src->ctp_reserved1[i],
dst->ctp_reserved1[i]);
ISP_IOXGET_16(isp, &src->ctp_reserved2[i],
dst->ctp_reserved2[i]);
}
ISP_IOXGET_32(isp, &src->ctp_rsp_bcnt, dst->ctp_rsp_bcnt);
ISP_IOXGET_32(isp, &src->ctp_cmd_bcnt, dst->ctp_cmd_bcnt);
@@ -1110,13 +1291,14 @@ isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *src, isp_ct_pt_t *dst)
ISP_IOXPUT_16(isp, src->ctp_status, &dst->ctp_status);
ISP_IOXPUT_16(isp, src->ctp_nphdl, &dst->ctp_nphdl);
ISP_IOXPUT_16(isp, src->ctp_cmd_cnt, &dst->ctp_cmd_cnt);
ISP_IOXPUT_16(isp, src->ctp_vpidx, &dst->ctp_vpidx);
ISP_IOXPUT_8(isp, src->ctp_vpidx, &dst->ctp_vpidx);
ISP_IOXPUT_8(isp, src->ctp_reserved0, &dst->ctp_reserved0);
ISP_IOXPUT_16(isp, src->ctp_time, &dst->ctp_time);
ISP_IOXPUT_16(isp, src->ctp_reserved0, &dst->ctp_reserved0);
ISP_IOXPUT_16(isp, src->ctp_reserved1, &dst->ctp_reserved1);
ISP_IOXPUT_16(isp, src->ctp_rsp_cnt, &dst->ctp_rsp_cnt);
for (i = 0; i < 5; i++) {
ISP_IOXPUT_16(isp, src->ctp_reserved1[i],
&dst->ctp_reserved1[i]);
ISP_IOXPUT_16(isp, src->ctp_reserved2[i],
&dst->ctp_reserved2[i]);
}
ISP_IOXPUT_32(isp, src->ctp_rsp_bcnt, &dst->ctp_rsp_bcnt);
ISP_IOXPUT_32(isp, src->ctp_cmd_bcnt, &dst->ctp_cmd_bcnt);
@@ -1420,15 +1602,9 @@ isp_get_fc_hdr(ispsoftc_t *isp, fc_hdr_t *src, fc_hdr_t *dst)
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);
/* XXX SOMETHING WAS AND STILL CONTINUES WRONG HERE XXX */
#if 0
ISP_IOZGET_16(isp, &src->ox_id, dst->ox_id);
ISP_IOZGET_16(isp, &src->rx_id, dst->rx_id);
#else
ISP_IOZGET_32(isp, &src->ox_id, dst->parameter);
dst->ox_id = dst->parameter;
dst->rx_id = dst->parameter >> 16;
#endif
ISP_IOZGET_32(isp, &src->parameter, dst->parameter);
}
+117 -187
View File
@@ -1,4 +1,4 @@
/* $Id: isp_library.h,v 1.25 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: isp_library.h,v 1.26 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -52,200 +52,130 @@
*
* gplbsd at feral com
*/
#ifndef _ISP_LIBRARY_H
#define _ISP_LIBRARY_H
#ifndef _ISP_LIBRARY_H
#define _ISP_LIBRARY_H
extern const char *isp_class3_roles[4];
extern int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
extern XS_T *isp_find_xs(ispsoftc_t *, uint32_t);
extern uint32_t isp_find_handle(ispsoftc_t *, XS_T *);
extern uint32_t isp_handle_index(uint32_t);
extern void isp_destroy_handle(ispsoftc_t *, uint32_t);
extern int isp_getrqentry(ispsoftc_t *, uint32_t *, uint32_t *, void **);
extern void isp_print_qentry (ispsoftc_t *, char *, int, void *);
extern void isp_print_bytes(ispsoftc_t *, const char *, int, void *);
extern int isp_fc_runstate(ispsoftc_t *, int);
extern void isp_dump_portdb(ispsoftc_t *);
extern void isp_shutdown(ispsoftc_t *);
extern void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
extern void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
extern int isp_get_response_type(ispsoftc_t *, isphdr_t *);
extern void
isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
extern void
isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
extern void
isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
extern void
isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
extern void
isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
extern void
isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
extern void
isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
extern void
isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
extern void
isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
extern void
isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
extern void
isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
extern void
isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
extern void
isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
extern void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *,
isp24xx_statusreq_t *);
void
isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
extern void
isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
extern void
isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
extern void
isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
extern void
isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
extern void
isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
extern void
isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
extern void
isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
extern void
isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
extern void
isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
extern void
isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
extern void
isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
extern void
isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
extern void
isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *,
sns_gid_ft_req_t *);
extern void
isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *,
sns_gxn_id_req_t *);
extern void
isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int);
extern void
isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *,
sns_gid_ft_rsp_t *, int);
extern void
isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *,
sns_gxn_id_rsp_t *);
extern void
isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *,
sns_gff_id_rsp_t *);
extern void
isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *,
sns_ga_nxt_rsp_t *);
extern void
isp_get_els(ispsoftc_t *, els_t *, els_t *);
extern void
isp_put_els(ispsoftc_t *, els_t *, els_t *);
extern void
isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
extern void
isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
extern void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
extern void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
extern void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
/* XXXXXX BARF - CLEAN UP THIS MESS XXXXXXXX*/
int isp_save_xs(ispsoftc_t *, XS_T *, uint32_t *);
XS_T * isp_find_xs(ispsoftc_t *, uint32_t);
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_bytes(ispsoftc_t *, const char *, int, void *);
int isp_fc_runstate(ispsoftc_t *, int, int);
void isp_dump_portdb(ispsoftc_t *, int);
void isp_shutdown(ispsoftc_t *);
void isp_put_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
void isp_get_hdr(ispsoftc_t *, isphdr_t *, isphdr_t *);
int isp_get_response_type(ispsoftc_t *, isphdr_t *);
#define ISP_HANDLE_MASK 0x7fff
void isp_put_request(ispsoftc_t *, ispreq_t *, ispreq_t *);
void isp_put_marker(ispsoftc_t *, isp_marker_t *, isp_marker_t *);
void isp_put_marker_24xx(ispsoftc_t *, isp_marker_24xx_t *, isp_marker_24xx_t *);
void isp_put_request_t2(ispsoftc_t *, ispreqt2_t *, ispreqt2_t *);
void isp_put_request_t2e(ispsoftc_t *, ispreqt2e_t *, ispreqt2e_t *);
void isp_put_request_t3(ispsoftc_t *, ispreqt3_t *, ispreqt3_t *);
void isp_put_request_t3e(ispsoftc_t *, ispreqt3e_t *, ispreqt3e_t *);
void isp_put_extended_request(ispsoftc_t *, ispextreq_t *, ispextreq_t *);
void isp_put_request_t7(ispsoftc_t *, ispreqt7_t *, ispreqt7_t *);
void isp_put_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
void isp_put_cont_req(ispsoftc_t *, ispcontreq_t *, ispcontreq_t *);
void isp_put_cont64_req(ispsoftc_t *, ispcontreq64_t *, ispcontreq64_t *);
void isp_get_response(ispsoftc_t *, ispstatusreq_t *, ispstatusreq_t *);
void isp_get_24xx_response(ispsoftc_t *, isp24xx_statusreq_t *, isp24xx_statusreq_t *);
void isp_get_24xx_abrt(ispsoftc_t *, isp24xx_abrt_t *, isp24xx_abrt_t *);
void isp_get_rio2(ispsoftc_t *, isp_rio2_t *, isp_rio2_t *);
void isp_put_icb(ispsoftc_t *, isp_icb_t *, isp_icb_t *);
void isp_put_icb_2400(ispsoftc_t *, isp_icb_2400_t *, isp_icb_2400_t *);
void isp_put_icb_2400_vpinfo(ispsoftc_t *, isp_icb_2400_vpinfo_t *, isp_icb_2400_vpinfo_t *);
void isp_put_vp_port_info(ispsoftc_t *, vp_port_info_t *, vp_port_info_t *);
void isp_get_vp_port_info(ispsoftc_t *, vp_port_info_t *, vp_port_info_t *);
void isp_put_vp_ctrl_info(ispsoftc_t *, vp_ctrl_info_t *, vp_ctrl_info_t *);
void isp_get_vp_ctrl_info(ispsoftc_t *, vp_ctrl_info_t *, vp_ctrl_info_t *);
void isp_put_vp_modify(ispsoftc_t *, vp_modify_t *, vp_modify_t *);
void isp_get_vp_modify(ispsoftc_t *, vp_modify_t *, vp_modify_t *);
void isp_get_pdb_21xx(ispsoftc_t *, isp_pdb_21xx_t *, isp_pdb_21xx_t *);
void isp_get_pdb_24xx(ispsoftc_t *, isp_pdb_24xx_t *, isp_pdb_24xx_t *);
void isp_get_ridacq(ispsoftc_t *, isp_ridacq_t *, isp_ridacq_t *);
void isp_get_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
void isp_put_plogx(ispsoftc_t *, isp_plogx_t *, isp_plogx_t *);
void isp_get_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
void isp_get_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
void isp_put_ct_pt(ispsoftc_t *isp, isp_ct_pt_t *, isp_ct_pt_t *);
void isp_put_ms(ispsoftc_t *isp, isp_ms_t *, isp_ms_t *);
void isp_put_sns_request(ispsoftc_t *, sns_screq_t *, sns_screq_t *);
void isp_put_gid_ft_request(ispsoftc_t *, sns_gid_ft_req_t *, sns_gid_ft_req_t *);
void isp_put_gxn_id_request(ispsoftc_t *, sns_gxn_id_req_t *, sns_gxn_id_req_t *);
void isp_get_sns_response(ispsoftc_t *, sns_scrsp_t *, sns_scrsp_t *, int);
void isp_get_gid_ft_response(ispsoftc_t *, sns_gid_ft_rsp_t *, sns_gid_ft_rsp_t *, int);
void isp_get_gxn_id_response(ispsoftc_t *, sns_gxn_id_rsp_t *, sns_gxn_id_rsp_t *);
void isp_get_gff_id_response(ispsoftc_t *, sns_gff_id_rsp_t *, sns_gff_id_rsp_t *);
void isp_get_ga_nxt_response(ispsoftc_t *, sns_ga_nxt_rsp_t *, sns_ga_nxt_rsp_t *);
void isp_get_els(ispsoftc_t *, els_t *, els_t *);
void isp_put_els(ispsoftc_t *, els_t *, els_t *);
void isp_get_fc_hdr(ispsoftc_t *, fc_hdr_t *, fc_hdr_t *);
void isp_get_fcp_cmnd_iu(ispsoftc_t *, fcp_cmnd_iu_t *, fcp_cmnd_iu_t *);
void isp_put_rft_id(ispsoftc_t *, rft_id_t *, rft_id_t *);
void isp_get_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
void isp_put_ct_hdr(ispsoftc_t *isp, ct_hdr_t *, ct_hdr_t *);
#ifdef ISP_TARGET_MODE
#if defined(__NetBSD__) || defined(__OpenBSD__)
#define ISP_HANDLE_MASK 0x7fff
#ifdef ISP_TARGET_MODE
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <dev/ic/isp_target.h>
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__)
#include <dev/isp/isp_target.h>
#else
#include "isp_target.h"
#endif
#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
#define IS_TARGET_HANDLE(x) ((x) & 0x8000)
extern int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
extern void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
extern uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
extern void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
int isp_save_xs_tgt(ispsoftc_t *, void *, uint32_t *);
void *isp_find_xs_tgt(ispsoftc_t *, uint32_t);
uint32_t isp_find_tgt_handle(ispsoftc_t *, void *);
void isp_destroy_tgt_handle(ispsoftc_t *, uint32_t);
extern void
isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
extern void
isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
extern void
isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
extern void
isp_put_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
extern void
isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
extern void
isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
extern void
isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
extern void
isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
extern void
isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
extern void
isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
extern void
isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
extern void
isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
extern void
isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
extern void
isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
extern void
isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
extern void
isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
extern void
isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
extern void
isp_put_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
extern void
isp_get_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
extern void
isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
extern void
isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
extern void
isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
extern void
isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
extern void
isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
extern void
isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
extern void
isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
extern void
isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
extern void
isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
extern void
isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
extern void
isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
extern void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
na_fcentry_24xx_t *);
extern void
isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
extern void
isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
extern void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *,
na_fcentry_24xx_t *);
extern void
isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
extern void
isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
extern void
isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
#endif /* ISP_TARGET_MODE */
#endif /* _ISP_LIBRARY_H */
void isp_put_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
void isp_get_atio(ispsoftc_t *, at_entry_t *, at_entry_t *);
void isp_put_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
void isp_put_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
void isp_get_atio2(ispsoftc_t *, at2_entry_t *, at2_entry_t *);
void isp_get_atio2e(ispsoftc_t *, at2e_entry_t *, at2e_entry_t *);
void isp_get_atio7(ispsoftc_t *isp, at7_entry_t *, at7_entry_t *);
void isp_put_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
void isp_get_ctio(ispsoftc_t *, ct_entry_t *, ct_entry_t *);
void isp_put_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
void isp_put_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
void isp_put_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
void isp_get_ctio2(ispsoftc_t *, ct2_entry_t *, ct2_entry_t *);
void isp_get_ctio2e(ispsoftc_t *, ct2e_entry_t *, ct2e_entry_t *);
void isp_get_ctio7(ispsoftc_t *, ct7_entry_t *, ct7_entry_t *);
void isp_put_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
void isp_get_enable_lun(ispsoftc_t *, lun_entry_t *, lun_entry_t *);
void isp_put_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
void isp_get_notify(ispsoftc_t *, in_entry_t *, in_entry_t *);
void isp_put_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
void isp_put_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
void isp_put_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
void isp_get_notify_fc(ispsoftc_t *, in_fcentry_t *, in_fcentry_t *);
void isp_get_notify_fc_e(ispsoftc_t *, in_fcentry_e_t *, in_fcentry_e_t *);
void isp_get_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *, in_fcentry_24xx_t *);
void isp_put_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
void isp_get_notify_ack(ispsoftc_t *, na_entry_t *, na_entry_t *);
void isp_put_notify_24xx_ack(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
void isp_put_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
void isp_put_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
void isp_put_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
void isp_get_notify_ack_fc(ispsoftc_t *, na_fcentry_t *, na_fcentry_t *);
void isp_get_notify_ack_fc_e(ispsoftc_t *, na_fcentry_e_t *, na_fcentry_e_t *);
void isp_get_notify_ack_24xx(ispsoftc_t *, na_fcentry_24xx_t *, na_fcentry_24xx_t *);
void isp_get_abts(ispsoftc_t *, abts_t *, abts_t *);
void isp_put_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
void isp_get_abts_rsp(ispsoftc_t *, abts_rsp_t *, abts_rsp_t *);
#endif /* ISP_TARGET_MODE */
#endif /* _ISP_LIBRARY_H */
+4 -1
View File
@@ -1,4 +1,4 @@
/* $Id: isp_stds.h,v 1.12 2007/10/29 18:11:08 mjacob Exp $ */
/* $Id: isp_stds.h,v 1.13 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -213,7 +213,10 @@ typedef struct {
#define ABTX 0x06
#define PRLI 0x20
#define PRLO 0x21
#define SCN 0x22
#define TPRLO 0x24
#define PDISC 0x50
#define ADISC 0x52
#define RNC 0x53
/*
+152 -82
View File
@@ -1,4 +1,4 @@
/* $Id: isp_target.c,v 1.70 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: isp_target.c,v 1.71 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -94,6 +94,7 @@ static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
static void isp_handle_ctio2(ispsoftc_t *, ct2_entry_t *);
static void isp_handle_ctio7(ispsoftc_t *, ct7_entry_t *);
static void isp_handle_24xx_inotify(ispsoftc_t *, in_fcentry_24xx_t *);
/*
* The Qlogic driver gets an interrupt to look at response queue entries.
@@ -231,7 +232,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
/*
* Just go straight to outer layer for this one.
*/
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
isp_async(isp, ISPASYNC_TARGET_ACTION, local);
} else {
isp_get_atio(isp, atiop, (at_entry_t *) local);
isp_handle_atio(isp, (at_entry_t *) local);
@@ -244,7 +245,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
break;
case RQSTYPE_ATIO2:
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_get_atio2e(isp, at2eiop, (at2e_entry_t *) local);
} else {
isp_get_atio2(isp, at2iop, (at2_entry_t *) local);
@@ -254,7 +255,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
case RQSTYPE_CTIO3:
case RQSTYPE_CTIO2:
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_get_ctio2e(isp, ct2eiop, (ct2e_entry_t *) local);
} else {
isp_get_ctio2(isp, ct2iop, (ct2_entry_t *) local);
@@ -270,7 +271,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
case RQSTYPE_ENABLE_LUN:
case RQSTYPE_MODIFY_LUN:
isp_get_enable_lun(isp, lunenp, (lun_entry_t *) local);
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
isp_async(isp, ISPASYNC_TARGET_ACTION, local);
break;
case RQSTYPE_NOTIFY:
@@ -286,32 +287,10 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
isp_get_notify_24xx(isp, inot_24xx,
(in_fcentry_24xx_t *)local);
inot_24xx = (in_fcentry_24xx_t *) local;
status = inot_24xx->in_status;
seqid = inot_24xx->in_rxid;
isp_prt(isp, ISP_LOGTDEBUG0,
"Immediate Notify status=0x%x seqid=0x%x",
status, seqid);
switch (status) {
case IN24XX_LIP_RESET:
case IN24XX_LINK_RESET:
case IN24XX_PORT_LOGOUT:
case IN24XX_PORT_CHANGED:
case IN24XX_LINK_FAILED:
case IN24XX_SRR_RCVD:
case IN24XX_ELS_RCVD:
(void) isp_async(isp, ISPASYNC_TARGET_ACTION,
&local);
break;
default:
isp_prt(isp, ISP_LOGINFO,
"isp_target_notify: unknown status (0x%x)",
status);
isp_notify_ack(isp, local);
break;
}
isp_handle_24xx_inotify(isp, inot_24xx);
break;
} else if (IS_FC(isp)) {
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_get_notify_fc_e(isp, inote_fcp,
(in_fcentry_e_t *)local);
} else {
@@ -365,14 +344,14 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
notify.nt_tagval = TAG_ANY;
notify.nt_ncode = NT_BUS_RESET;
notify.nt_need_ack = 1;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
}
case IN_PORT_LOGOUT:
case IN_ABORT_TASK:
case IN_PORT_CHANGED:
case IN_GLOBAL_LOGO:
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
break;
default:
isp_prt(isp, ISP_LOGINFO,
@@ -402,7 +381,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
nack_24xx->na_status, nack_24xx->na_status_subcode,
nack_24xx->na_rxid);
} else if (IS_FC(isp)) {
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_get_notify_ack_fc_e(isp, nacke_fcp,
(na_fcentry_e_t *)local);
} else {
@@ -434,7 +413,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
case RQSTYPE_ABTS_RCVD:
isp_get_abts(isp, abts, (abts_t *)local);
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
break;
case RQSTYPE_ABTS_RSP:
isp_get_abts_rsp(isp, abts_rsp, (abts_rsp_t *)local);
@@ -482,7 +461,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
/*
* Toggle (on/off) target mode for bus/target/lun
* Toggle (on/off) target mode for bus/target/lun.
*
* The caller has checked for overlap and legality.
*
@@ -491,8 +470,7 @@ isp_target_notify(ispsoftc_t *isp, void *vptr, uint32_t *optrp)
* response entry. The caller is responsible for synchronizing this.
*/
int
isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
int cmd_cnt, int inot_cnt, uint32_t opaque)
isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int lun, int cmd_cnt, int inot_cnt)
{
lun_entry_t el;
uint32_t nxti, optr;
@@ -523,11 +501,10 @@ isp_lun_cmd(ispsoftc_t *isp, int cmd, int bus, int tgt, int lun,
}
el.le_header.rqs_entry_type = cmd;
el.le_header.rqs_entry_count = 1;
el.le_reserved = opaque;
if (IS_SCSI(isp)) {
el.le_tgt = tgt;
el.le_tgt = SDPARAM(isp, bus)->isp_initiator_id;
el.le_lun = lun;
} else if (FCPARAM(isp)->isp_sccfw == 0) {
} else if (ISP_CAP_SCCFW(isp) == 0) {
el.le_lun = lun;
}
el.le_timeout = 30;
@@ -561,7 +538,7 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap)
isp_put_atio(isp, (at_entry_t *) ap, (at_entry_t *) outp);
break;
case RQSTYPE_ATIO2:
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_atio2e(isp, (at2e_entry_t *) ap,
(at2e_entry_t *) outp);
} else {
@@ -573,7 +550,7 @@ isp_target_put_entry(ispsoftc_t *isp, void *ap)
isp_put_ctio(isp, (ct_entry_t *) ap, (ct_entry_t *) outp);
break;
case RQSTYPE_CTIO2:
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_ctio2e(isp, (ct2e_entry_t *) ap,
(ct2e_entry_t *) outp);
} else {
@@ -608,12 +585,12 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
at2_entry_t *aep = arg;
atun._atio2.at_header.rqs_entry_type = RQSTYPE_ATIO2;
atun._atio2.at_header.rqs_entry_count = 1;
if (FCPARAM(isp)->isp_sccfw) {
if (ISP_CAP_SCCFW(isp)) {
atun._atio2.at_scclun = aep->at_scclun;
} else {
atun._atio2.at_lun = (uint8_t) aep->at_lun;
}
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
atun._atio2e.at_iid = ((at2e_entry_t *)aep)->at_iid;
} else {
atun._atio2.at_iid = aep->at_iid;
@@ -655,32 +632,44 @@ isp_target_put_atio(ispsoftc_t *isp, void *arg)
*/
int
isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
isp_endcmd(ispsoftc_t *isp, ...)
{
int sts;
uint32_t code, hdl;
uint8_t sts;
union {
ct_entry_t _ctio;
ct2_entry_t _ctio2;
ct2e_entry_t _ctio2e;
ct7_entry_t _ctio7;
} un;
va_list ap;
MEMZERO(&un, sizeof un);
sts = code & 0xff;
if (IS_24XX(isp)) {
at7_entry_t *aep = arg;
int vpidx, nphdl;
at7_entry_t *aep;
ct7_entry_t *cto = &un._ctio7;
va_start(ap, isp);
aep = va_arg(ap, at7_entry_t *);
nphdl = va_arg(ap, int);
vpidx = va_arg(ap, int);
code = va_arg(ap, uint32_t);
hdl = va_arg(ap, uint32_t);
va_end(ap);
sts = code;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
cto->ct_header.rqs_entry_count = 1;
/* XXXX */ cto->ct_nphdl = aep->at_hdr.seq_id;
cto->ct_nphdl = nphdl;
cto->ct_rxid = aep->at_rxid;
cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
aep->at_hdr.s_id[2];
cto->ct_iid_hi = aep->at_hdr.s_id[0];
cto->ct_oxid = aep->at_hdr.ox_id;
cto->ct_scsi_status = sts;
cto->ct_vpindex = vpidx;
cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
cto->rsp.m1.ct_resplen = 16;
@@ -696,15 +685,22 @@ isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
}
cto->ct_syshandle = hdl;
} else if (IS_FC(isp)) {
at2_entry_t *aep = arg;
at2_entry_t *aep;
ct2_entry_t *cto = &un._ctio2;
va_start(ap, isp);
aep = va_arg(ap, at2_entry_t *);
code = va_arg(ap, uint32_t);
hdl = va_arg(ap, uint32_t);
va_end(ap);
sts = code;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
cto->ct_header.rqs_entry_count = 1;
if (FCPARAM(isp)->isp_sccfw == 0) {
if (ISP_CAP_SCCFW(isp) == 0) {
cto->ct_lun = aep->at_lun;
}
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
un._ctio2e.ct_iid = ((at2e_entry_t *)aep)->at_iid;
} else {
cto->ct_iid = aep->at_iid;
@@ -730,9 +726,16 @@ isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
}
cto->ct_syshandle = hdl;
} else {
at_entry_t *aep = arg;
at_entry_t *aep;
ct_entry_t *cto = &un._ctio;
va_start(ap, isp);
aep = va_arg(ap, at_entry_t *);
code = va_arg(ap, uint32_t);
hdl = va_arg(ap, uint32_t);
va_end(ap);
sts = code;
cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
cto->ct_header.rqs_entry_count = 1;
cto->ct_fwhandle = aep->at_handle;
@@ -767,6 +770,7 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
notify.nt_iid = INI_ANY;
/* nt_tgt set in outer layers */
notify.nt_lun = LUN_ANY;
notify.nt_channel = bus;
notify.nt_tagval = TAG_ANY;
if (IS_SCSI(isp)) {
@@ -777,27 +781,27 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
case ASYNC_LOOP_UP:
case ASYNC_PTPMODE:
notify.nt_ncode = NT_LINK_UP;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_LOOP_DOWN:
notify.nt_ncode = NT_LINK_DOWN;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_LIP_ERROR:
case ASYNC_LIP_F8:
case ASYNC_LIP_OCCURRED:
case ASYNC_LOOP_RESET:
notify.nt_ncode = NT_LIP_RESET;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_BUS_RESET:
case ASYNC_TIMEOUT_RESET: /* XXX: where does this come from ? */
notify.nt_ncode = NT_BUS_RESET;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_DEVICE_RESET:
notify.nt_ncode = NT_TARGET_RESET;
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
break;
case ASYNC_CTIO_DONE:
{
@@ -823,7 +827,7 @@ isp_target_async(ispsoftc_t *isp, int bus, int event)
ct->ct_fwhandle = bus;
ct->ct_flags = CT_SENDSTATUS;
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
break;
}
default:
@@ -889,7 +893,7 @@ isp_got_msg(ispsoftc_t *isp, in_entry_t *inp)
isp_notify_ack(isp, inp);
return;
}
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
} else {
isp_prt(isp, ISP_LOGERR,
"unknown immediate notify status 0x%x", inp->in_status);
@@ -911,7 +915,7 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
MEMZERO(&nt, sizeof (tmd_notify_t));
nt.nt_hba = isp;
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
nt.nt_iid = ((in_fcentry_e_t *)inp)->in_iid;
loopid = ((in_fcentry_e_t *)inp)->in_iid;
seqid = ((in_fcentry_e_t *)inp)->in_seqid;
@@ -921,7 +925,7 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
seqid = inp->in_seqid;
}
/* nt_tgt set in outer layers */
if (FCPARAM(isp)->isp_sccfw) {
if (ISP_CAP_SCCFW(isp)) {
nt.nt_lun = inp->in_scclun;
} else {
nt.nt_lun = inp->in_lun;
@@ -964,7 +968,7 @@ isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
isp_notify_ack(isp, inp);
return;
}
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
}
#define HILO(x) (uint32_t) (x >> 32), (uint32_t) x
@@ -976,7 +980,8 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
"%s from PortID 0x%06x lun %d seq 0x%08x%08x";
static const char f2[] =
"unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%08x%08x";
uint32_t sid;
uint16_t chan;
uint32_t sid, did;
MEMZERO(&nt, sizeof (tmd_notify_t));
nt.nt_hba = isp;
@@ -984,9 +989,6 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
nt.nt_lun =
(aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
(aep->at_cmnd.fcp_cmnd_lun[1]);
/*
* XXX: VPIDX HAS TO BE DERIVED FROM DESTINATION PORT
*/
nt.nt_tagval = aep->at_rxid;
nt.nt_lreserved = aep;
sid =
@@ -994,6 +996,20 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
(aep->at_hdr.s_id[1] << 8) |
(aep->at_hdr.s_id[2]);
/* Channel has to derived from D_ID */
did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2];
for (chan = 0; chan < isp->isp_nchan; chan++) {
if (FCPARAM(isp, chan)->isp_portid == did) {
break;
}
}
if (chan == isp->isp_nchan) {
isp_prt(isp, ISP_LOGWARN,
"%s: D_ID 0x%x not found on any channel", __FUNCTION__, did);
/* just drop on the floor */
return;
}
nt.nt_channel = chan;
if (aep->at_cmnd.fcp_cmnd_task_management &
FCP_CMND_TMF_ABORT_TASK_SET) {
isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
@@ -1024,10 +1040,10 @@ isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
isp_prt(isp, ISP_LOGWARN, f2,
aep->at_cmnd.fcp_cmnd_task_management,
nt.nt_lun, sid, HILO(nt.nt_tagval));
isp_endcmd(isp, aep, 0, 0);
nt.nt_ncode = NT_UNKNOWN;
return;
}
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
}
void
@@ -1047,7 +1063,8 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
at7_entry_t *aep = arg;
isp_endcmd(isp, aep, 0, 0);
isp_prt(isp, ISP_LOGWARN, "SQUAWK: notify ack with no known vpidx or nphdl");
isp_endcmd(isp, aep, NIL_HANDLE, 0, 0, 0);
return;
} else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
@@ -1066,11 +1083,12 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
na->na_status_subcode = in->in_status_subcode;
na->na_rxid = in->in_rxid;
na->na_oxid = in->in_oxid;
na->na_vpindex = in->in_vpindex;
na->na_srr_rxid = in->in_srr_rxid;
na->na_srr_reloff_hi = in->in_srr_reloff_hi;
na->na_srr_reloff_lo = in->in_srr_reloff_lo;
na->na_srr_iu = in->in_srr_iu;
if (in->in_status == IN24XX_SRR_RCVD) {
na->na_srr_rxid = in->in_srr_rxid;
na->na_srr_reloff_hi = in->in_srr_reloff_hi;
na->na_srr_reloff_lo = in->in_srr_reloff_lo;
na->na_srr_iu = in->in_srr_iu;
na->na_srr_flags = 1;
na->na_srr_reject_vunique = 0;
na->na_srr_reject_explanation = 1;
@@ -1087,7 +1105,7 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
if (arg) {
in_fcentry_t *inp = arg;
MEMCPY(storage, arg, sizeof (isphdr_t));
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
((na_fcentry_e_t *)na)->na_iid =
((in_fcentry_e_t *)inp)->in_iid;
iid = ((na_fcentry_e_t *)na)->na_iid;
@@ -1112,7 +1130,7 @@ isp_notify_ack(ispsoftc_t *isp, void *arg)
}
na->na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;
na->na_header.rqs_entry_count = 1;
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_notify_ack_fc_e(isp, (na_fcentry_e_t *) na,
(na_fcentry_e_t *)outp);
} else {
@@ -1202,7 +1220,7 @@ isp_handle_atio(ispsoftc_t *isp, at_entry_t *aep)
/*
* Punt to platform specific layer.
*/
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
break;
case AT_RESET:
@@ -1233,13 +1251,13 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
{
int lun, iid;
if (FCPARAM(isp)->isp_sccfw) {
if (ISP_CAP_SCCFW(isp)) {
lun = aep->at_scclun;
} else {
lun = aep->at_lun;
}
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
iid = ((at2e_entry_t *)aep)->at_iid;
} else {
iid = aep->at_iid;
@@ -1292,7 +1310,7 @@ isp_handle_atio2(ispsoftc_t *isp, at2_entry_t *aep)
/*
* Punt to platform specific layer.
*/
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
isp_async(isp, ISPASYNC_TARGET_ACTION, aep);
break;
case AT_RESET:
@@ -1474,7 +1492,7 @@ isp_handle_ctio(ispsoftc_t *isp, ct_entry_t *ct)
/*
* The platform layer will destroy the handle if appropriate.
*/
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
}
}
@@ -1633,7 +1651,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
*/
isp_prt(isp, pl, "data CTIO complete");
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
/*
* The platform layer will destroy the handle if appropriate.
*/
@@ -1786,10 +1804,62 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
*/
isp_prt(isp, pl, "data CTIO complete");
}
(void) isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
isp_async(isp, ISPASYNC_TARGET_ACTION, ct);
/*
* The platform layer will destroy the handle if appropriate.
*/
}
}
static void
isp_handle_24xx_inotify(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
{
uint8_t ochan, chan, lochan, hichan;
/*
* Check to see whether we got a wildcard channel.
* If so, we have to iterate over all channels.
*/
ochan = chan = inot_24xx->in_vpindex;
if (chan == 0xff) {
lochan = 0;
hichan = isp->isp_nchan;
} else {
if (chan > isp->isp_nchan) {
isp_prt(isp, ISP_LOGINFO,
"%s: bad channel %d for status 0x%x",
__FUNCTION__, chan, inot_24xx->in_status);
isp_notify_ack(isp, inot_24xx);
return;
}
lochan = chan;
hichan = chan + 1;
}
isp_prt(isp, ISP_LOGTDEBUG0,
"%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x",
__FUNCTION__, lochan, hichan-1, inot_24xx->in_status,
inot_24xx->in_rxid);
for (chan = lochan; chan < hichan; chan++) {
switch (inot_24xx->in_status) {
case IN24XX_LIP_RESET:
case IN24XX_LINK_RESET:
case IN24XX_PORT_LOGOUT:
case IN24XX_PORT_CHANGED:
case IN24XX_LINK_FAILED:
case IN24XX_SRR_RCVD:
case IN24XX_ELS_RCVD:
inot_24xx->in_vpindex = chan;
isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
break;
default:
isp_prt(isp, ISP_LOGINFO,
"%s: unhandled status (0x%x) for chan %d",
__FUNCTION__, inot_24xx->in_status, chan);
isp_notify_ack(isp, inot_24xx);
break;
}
}
inot_24xx->in_vpindex = ochan;
}
#endif
+7 -6
View File
@@ -1,4 +1,4 @@
/* $Id: isp_target.h,v 1.55 2007/10/29 18:12:02 mjacob Exp $ */
/* $Id: isp_target.h,v 1.56 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -458,7 +458,7 @@ typedef struct {
#define AT2_HAS_TAG(val) 1
#define AT2_GET_TAG(val) ((val) & 0xffffffff)
#define AT2_GET_INST(val) ((val) >> 32)
#define AT2_GET_INST(val) (((val) >> 32) & 0xffff)
#define AT2_GET_HANDLE AT2_GET_TAG
#define AT2_GET_BUS(val) (((val) >> 48) & 0xff)
@@ -473,7 +473,7 @@ typedef struct {
tid |= (((uint64_t)(bus & 0xff)) << 48)
#define FC_TAG_INSERT_INST(tid, inst) \
tid &= ~0xffff00000000ull; \
tid &= ~0x0000ffff00000000ull; \
tid |= (((uint64_t)inst) << 32)
/*
@@ -501,6 +501,7 @@ typedef struct {
fc_hdr_t at_hdr;
fcp_cmnd_iu_t at_cmnd;
} at7_entry_t;
#define AT7_NORESRC_RXID 0xffffffff
/*
@@ -936,11 +937,11 @@ void isp_notify_ack(ispsoftc_t *, void *);
/*
* Enable/Disable/Modify a logical unit.
* (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
* (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, int, uint32_t);
int isp_lun_cmd(ispsoftc_t *, int, int, int, int, int);
/*
* General request queue 'put' routine for target mode entries.
@@ -959,7 +960,7 @@ 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 *, void *, uint32_t, uint32_t);
int isp_endcmd(ispsoftc_t *, ...);
#define ECMD_SVALID 0x100
/*
+6 -6
View File
@@ -1,4 +1,4 @@
/* $Id: isp_tpublic.h,v 1.37 2007/11/13 01:25:50 mjacob Exp $ */
/* $Id: isp_tpublic.h,v 1.38 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -114,7 +114,7 @@ typedef enum {
*
* The r_version tag defines the version of this API.
*/
#define QR_VERSION 18
#define QR_VERSION 19
typedef struct {
/* NB: structure tags from here to r_version must never change */
void * r_identity;
@@ -165,6 +165,7 @@ typedef struct {
* 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,
@@ -194,7 +195,6 @@ typedef struct tmd_notify {
} tmd_notify_t;
#define LUN_ANY 0xffff
#define TGT_ANY ((uint64_t) -1)
#define INI_ANY ((uint64_t) -1)
#define TAG_ANY ((uint64_t) 0)
#define MATCH_TMD(tmd, iid, lun, tag) \
( \
@@ -208,7 +208,9 @@ typedef struct tmd_notify {
* Lun ENABLE/DISABLE
*
* A word about ENABLE/DISABLE: the argument is a pointer to a enadis_t
* with en_hba, en_iid, en_chan, en_tgt and en_lun filled out.
* with en_hba, en_chan and en_lun filled out. We used to have an iid
* and target pair, but this just gets silly so we made initiator id
* and target id something you set, once, elsewhere.
*
* If an error occurs in either enabling or disabling the described lun
* en_error is set with an appropriate non-zero value.
@@ -216,8 +218,6 @@ typedef struct tmd_notify {
typedef struct {
void * en_private; /* for outer layer usage */
void * en_hba; /* HBA tag */
uint64_t en_iid; /* initiator ID */
uint64_t en_tgt; /* target identifier */
uint16_t en_lun; /* logical unit */
uint16_t en_chan; /* channel on card */
int en_error;
+157 -21
View File
@@ -1,4 +1,4 @@
/* $Id: ispmbox.h,v 1.66 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: ispmbox.h,v 1.67 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -153,6 +153,9 @@
#define MBOX_GET_RESOURCE_COUNT 0x0042
#define MBOX_REQUEST_OFFLINE_MODE 0x0043
#define MBOX_ENHANCED_GET_PDB 0x0047
#define MBOX_INIT_FIRMWARE_MULTI_ID 0x0048 /* 2400 only */
#define MBOX_GET_VP_DATABASE 0x0049 /* 2400 only */
#define MBOX_GET_VP_DATABASE_ENTRY 0x004a /* 2400 only */
#define MBOX_EXEC_COMMAND_IOCB_A64 0x0054
#define MBOX_INIT_FIRMWARE 0x0060
#define MBOX_GET_INIT_CONTROL_BLOCK 0x0061
@@ -358,6 +361,9 @@ typedef struct {
#define RQSTYPE_IP_RECV_CONT 0x24
#define RQSTYPE_CT_PASSTHRU 0x29
#define RQSTYPE_MS_PASSTHRU 0x29
#define RQSTYPE_VP_CTRL 0x30 /* 24XX only */
#define RQSTYPE_VP_MODIFY 0x31 /* 24XX only */
#define RQSTYPE_RPT_ID_ACQ 0x32 /* 24XX only */
#define RQSTYPE_ABORT_IO 0x33
#define RQSTYPE_T6RQS 0x48
#define RQSTYPE_LOGIN 0x52
@@ -650,11 +656,12 @@ typedef struct {
uint16_t ctp_status;
uint16_t ctp_nphdl; /* n-port handle */
uint16_t ctp_cmd_cnt; /* Command DSD count */
uint16_t ctp_vpidx; /* low 8 bits */
uint8_t ctp_vpidx;
uint8_t ctp_reserved0;
uint16_t ctp_time;
uint16_t ctp_reserved0;
uint16_t ctp_reserved1;
uint16_t ctp_rsp_cnt; /* Response DSD count */
uint16_t ctp_reserved1[5];
uint16_t ctp_reserved2[5];
uint32_t ctp_rsp_bcnt; /* Response byte count */
uint32_t ctp_cmd_bcnt; /* Command byte count */
ispds64_t ctp_dataseg[2];
@@ -793,24 +800,33 @@ typedef struct {
* About Firmware returns an 'attribute' word in mailbox 6.
* These attributes are for 2200 and 2300.
*/
#define ISP_FW_ATTR_TMODE 0x01
#define ISP_FW_ATTR_SCCLUN 0x02
#define ISP_FW_ATTR_FABRIC 0x04
#define ISP_FW_ATTR_CLASS2 0x08
#define ISP_FW_ATTR_FCTAPE 0x10
#define ISP_FW_ATTR_IP 0x20
#define ISP_FW_ATTR_VI 0x40
#define ISP_FW_ATTR_VI_SOLARIS 0x80
#define ISP_FW_ATTR_2KLOGINS 0x100 /* XXX: just a guess */
#define ISP_FW_ATTR_TMODE 0x0001
#define ISP_FW_ATTR_SCCLUN 0x0002
#define ISP_FW_ATTR_FABRIC 0x0004
#define ISP_FW_ATTR_CLASS2 0x0008
#define ISP_FW_ATTR_FCTAPE 0x0010
#define ISP_FW_ATTR_IP 0x0020
#define ISP_FW_ATTR_VI 0x0040
#define ISP_FW_ATTR_VI_SOLARIS 0x0080
#define ISP_FW_ATTR_2KLOGINS 0x0100 /* just a guess... */
/* and these are for the 2400 */
#define ISP2400_FW_ATTR_CLASS2 (1 << 0)
#define ISP2400_FW_ATTR_IP (1 << 1)
#define ISP2400_FW_ATTR_MULTIID (1 << 2)
#define ISP2400_FW_ATTR_SB2 (1 << 3)
#define ISP2400_FW_ATTR_T10CRC (1 << 4)
#define ISP2400_FW_ATTR_VI (1 << 5)
#define ISP2400_FW_ATTR_EXPFW (1 << 13)
#define ISP2400_FW_ATTR_CLASS2 0x0001
#define ISP2400_FW_ATTR_IP 0x0002
#define ISP2400_FW_ATTR_MULTIID 0x0004
#define ISP2400_FW_ATTR_SB2 0x0008
#define ISP2400_FW_ATTR_T10CRC 0x0010
#define ISP2400_FW_ATTR_VI 0x0020
#define ISP2400_FW_ATTR_EXPFW 0x2000
#define ISP_CAP_TMODE(isp) \
(IS_24XX(isp)? 1 : (isp->isp_fwattr & ISP_FW_ATTR_TMODE))
#define ISP_CAP_SCCFW(isp) \
(IS_24XX(isp)? 1 : (isp->isp_fwattr & ISP_FW_ATTR_SCCLUN))
#define ISP_CAP_2KLOGIN(isp) \
(IS_24XX(isp)? 1 : (isp->isp_fwattr & ISP_FW_ATTR_2KLOGINS))
#define ISP_CAP_MULTI_ID(isp) \
(IS_24XX(isp)? (isp->isp_fwattr & ISP2400_FW_ATTR_MULTIID) : 0)
/*
* Reduced Interrupt Operation Response Queue Entreis
@@ -1048,6 +1064,93 @@ typedef struct {
((uint64_t) array[ICB_NNM6] << 48) | \
((uint64_t) array[ICB_NNM7] << 56)
/*
* For MULTI_ID firmware, this describes a
* virtual port entity for getting status.
*/
typedef struct {
uint16_t vp_port_status;
uint8_t vp_port_options;
uint8_t vp_port_loopid;
uint8_t vp_port_portname[8];
uint8_t vp_port_nodename[8];
uint16_t vp_port_portid_lo; /* not present when trailing icb */
uint16_t vp_port_portid_hi; /* not present when trailing icb */
} vp_port_info_t;
#define ICB2400_VPOPT_TGT_DISABLE 0x00000020 /* disable target mode */
#define ICB2400_VPOPT_INI_ENABLE 0x00000010 /* enable initiator mode */
#define ICB2400_VPOPT_ENABLED 0x00000008
#define ICB2400_VPOPT_NOPLAY 0x00000004
#define ICB2400_VPOPT_PREVLOOP 0x00000002
#define ICB2400_VPOPT_HARD_ADDRESS 0x00000001
#define ICB2400_VPOPT_WRITE_SIZE 20
/*
* For MULTI_ID firmware, we append this structure
* to the isp_icb_2400_t above, followed by a list
* structures that are *most* of the vp_port_info_t.
*/
typedef struct {
uint16_t vp_count;
uint16_t vp_global_options;
} isp_icb_2400_vpinfo_t;
#define ICB2400_VPINFO_OFF 0x80 /* offset from start of ICB */
#define ICB2400_VPINFO_PORT_OFF(chan) \
ICB2400_VPINFO_OFF + \
sizeof (isp_icb_2400_vpinfo_t) + ((chan - 1) * ICB2400_VPOPT_WRITE_SIZE)
typedef struct {
isphdr_t vp_ctrl_hdr;
uint32_t vp_ctrl_handle;
uint16_t vp_ctrl_index_fail;
uint16_t vp_ctrl_status;
uint16_t vp_ctrl_command;
uint16_t vp_ctrl_vp_count;
uint16_t vp_ctrl_idmap[8];
uint8_t vp_ctrl_reserved[32];
} vp_ctrl_info_t;
#define VP_CTRL_CMD_ENABLE_VP 0
#define VP_CTRL_CMD_DISABLE_VP 8
#define VP_CTRL_CMD_DISABLE_VP_REINIT_LINK 9
#define VP_CTRL_CMD_DISABLE_VP_LOGO 0xA
/*
* We can use this structure for modifying either one or two VP ports after initialization
*/
typedef struct {
isphdr_t vp_mod_hdr;
uint32_t vp_mod_hdl;
uint16_t vp_mod_reserved0;
uint16_t vp_mod_status;
uint8_t vp_mod_cmd;
uint8_t vp_mod_cnt;
uint8_t vp_mod_idx0;
uint8_t vp_mod_idx1;
struct {
uint8_t options;
uint8_t loopid;
uint16_t reserved1;
uint8_t wwpn[8];
uint8_t wwnn[8];
} vp_mod_ports[2];
uint8_t vp_mod_reserved2[8];
} vp_modify_t;
#define VP_STS_OK 0x00
#define VP_STS_ERR 0x01
#define VP_CNT_ERR 0x02
#define VP_GEN_ERR 0x03
#define VP_IDX_ERR 0x04
#define VP_STS_BSY 0x05
#define VP_MODIFY_VP 0x00
#define VP_MODIFY_ENA 0x01
/*
* Port Data Base Element
*/
@@ -1164,6 +1267,7 @@ typedef struct {
*/
typedef struct {
uint16_t handle;
uint16_t channel;
uint32_t
flags : 8,
portid : 24;
@@ -1227,6 +1331,36 @@ typedef struct {
#define PLOGX_FLG_CLASS2 0x100 /* if with PLOGI */
#define PLOGX_FLG_FCP2_OVERRIDE 0x200 /* if with PRLOG, PRLI */
/*
* Report ID Acquisistion (24XX multi-id firmware)
*/
typedef struct {
isphdr_t ridacq_hdr;
uint32_t ridacq_handle;
union {
struct {
uint8_t ridacq_vp_acquired;
uint8_t ridacq_vp_setup;
uint16_t ridacq_reserved0;
} type0; /* type 0 */
struct {
uint16_t ridacq_vp_count;
uint8_t ridacq_vp_index;
uint8_t ridacq_vp_status;
} type1; /* type 1 */
} un;
uint16_t ridacq_vp_port_lo;
uint8_t ridacq_vp_port_hi;
uint8_t ridacq_format; /* 0 or 1 */
uint16_t ridacq_map[8];
uint8_t ridacq_reserved1[32];
} isp_ridacq_t;
#define RIDACQ_STS_COMPLETE 0
#define RIDACQ_STS_UNACQUIRED 1
#define RIDACQ_STS_CHANGED 20
/*
* Simple Name Server Data Structures
*/
@@ -1417,7 +1551,9 @@ typedef struct {
typedef struct {
uint16_t handle;
uint16_t lun;
uint32_t portid;
uint32_t
channel : 8,
portid : 24;
uint32_t timeout;
union {
struct {
+6 -5
View File
@@ -1,4 +1,4 @@
/* $Id: ispreg.h,v 1.26 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: ispreg.h,v 1.27 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -389,11 +389,12 @@
#define BIU2400_REQOUTP (BIU_BLOCK+0x20) /* Request Queue Out */
#define BIU2400_RSPINP (BIU_BLOCK+0x24) /* Response Queue In */
#define BIU2400_RSPOUTP (BIU_BLOCK+0x28) /* Response Queue Out */
#define BIU2400_PRI_RQINP (BIU_BLOCK+0x2C) /* Priority Request Q In */
#define BIU2400_PRI_RSPINP (BIU_BLOCK+0x30) /* Priority Request Q Out */
#define BIU2400_ATIO_RSPINP (BIU_BLOCK+0x3C) /* ATIO Queue In */
#define BIU2400_ATIO_REQINP (BIU_BLOCK+0x40) /* ATIO Queue Out */
#define BIU2400_PRI_REQINP (BIU_BLOCK+0x2C) /* Priority Request Q In */
#define BIU2400_PRI_REQOUTP (BIU_BLOCK+0x30) /* Priority Request Q Out */
#define BIU2400_ATIO_RSPINP (BIU_BLOCK+0x3C) /* ATIO Queue In */
#define BIU2400_ATIO_RSPOUTP (BIU_BLOCK+0x40) /* ATIO Queue Out */
#define BIU2400_R2HSTSLO (BIU_BLOCK+0x44)
#define BIU2400_R2HSTSHI (BIU_BLOCK+0x46)
+163 -153
View File
@@ -1,4 +1,4 @@
/* $Id: ispvar.h,v 1.85 2007/10/30 01:54:46 mjacob Exp $ */
/* $Id: ispvar.h,v 1.86 2007/12/02 22:02:04 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -76,7 +76,7 @@
#include "ispmbox.h"
#endif
#define ISP_CORE_VERSION_MAJOR 3
#define ISP_CORE_VERSION_MAJOR 5
#define ISP_CORE_VERSION_MINOR 0
/*
@@ -189,9 +189,10 @@ struct ispmdvec {
* SCSI Specific Host Adapter Parameters- per bus, per target
*/
typedef struct {
uint32_t : 10,
isp_bad_nvram : 1,
isp_gotdparms : 1,
uint32_t : 8,
update : 1,
sendmarker : 1,
role : 2,
isp_req_ack_active_neg : 1,
isp_data_line_active_neg: 1,
isp_cmd_dma_burst_enable: 1,
@@ -264,6 +265,9 @@ typedef struct {
#define SNS_ID 0x80 /* SNS Server Special ID */
#define NPH_MAX 0xfe
/* Use this handle for the base for multi-id firmware SNS logins */
#define NPH_SNS_HDLBASE 0x400
/* These are for 2K Login Firmware cards */
#define NPH_RESERVED 0x7F0 /* begin of reserved N-port handles */
#define NPH_MGT_ID 0x7FA /* Management Server Special ID */
@@ -281,12 +285,21 @@ typedef struct {
*/
#define LOCAL_LOOP_LIM 126
/*
* Special Constants
*/
#define INI_NONE ((uint64_t) 0)
#define INI_ANY ((uint64_t) -1)
#define VALID_INI(ini) (ini != INI_NONE && ini != INI_ANY)
/*
* Special Port IDs
*/
#define MANAGEMENT_PORT_ID 0xFFFFFA
#define SNS_PORT_ID 0xFFFFFC
#define FABRIC_PORT_ID 0xFFFFFE
#define PORT_ANY 0xFFFFFF
#define PORT_NONE 0
/*
@@ -345,6 +358,7 @@ typedef struct {
* the 'loopid'.
*/
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.
@@ -352,17 +366,23 @@ typedef struct {
* A device is 'autologin' if the firmware automatically logs into
* it (re-logins as needed). Basically, local private loop devices.
*
* The state is the current state of thsi entry.
* The state is the current state of this entry.
*
* Role is Initiator, Target, Both
*
* Portid is obvious, as or node && port WWNs. The new_role and
* Portid is obvious, as are node && port WWNs. The new_role and
* new_portid is for when we are pending a change.
*
* 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
* with this set.
*/
uint16_t ini_map_idx : 12,
autologin : 1, /* F/W does PLOGI/PLOGO */
state : 3;
uint32_t reserved : 6,
uint32_t reserved : 5,
target_mode : 1,
roles : 2,
portid : 24;
uint32_t new_reserved : 6,
@@ -383,34 +403,44 @@ typedef struct {
/*
* FC card specific information
*
* This structure is replicated across multiple channels for multi-id
* capapble chipsets, with some entities different on a per-channel basis.
*/
typedef struct {
uint32_t : 10,
isp_tmode : 1,
isp_2klogin : 1,
isp_sccfw : 1,
isp_gbspeed : 3,
: 1,
: 1,
isp_gotdparms : 1,
isp_bad_nvram : 1,
uint32_t : 13,
sendmarker : 1,
role : 2,
isp_gbspeed : 4,
isp_loopstate : 4, /* Current Loop State */
isp_fwstate : 4, /* ISP F/W state */
isp_topo : 3,
isp_topo : 3, /* Connection Type */
loop_seen_once : 1;
uint32_t : 8,
isp_portid : 24; /* S_ID */
uint16_t isp_fwoptions;
uint16_t isp_xfwoptions;
uint16_t isp_zfwoptions;
uint16_t isp_loopid; /* hard loop id */
uint16_t isp_fwattr; /* firmware attributes */
uint16_t isp_execthrottle;
uint16_t isp_loopid; /* hard loop id */
uint16_t isp_sns_hdl; /* N-port handle for SNS */
uint16_t isp_lasthdl; /* only valid for channel 0 */
uint16_t isp_maxalloc;
uint8_t isp_retry_delay;
uint8_t isp_retry_count;
uint8_t isp_reserved;
uint16_t isp_maxalloc;
uint16_t isp_maxfrmlen;
/*
* Current active WWNN/WWPN
*/
uint64_t isp_wwnn;
uint64_t isp_wwpn;
/*
* NVRAM WWNN/WWPN
*/
uint64_t isp_wwnn_nvram;
uint64_t isp_wwpn_nvram;
@@ -434,6 +464,9 @@ typedef struct {
void * isp_scratch;
XS_DMA_ADDR_T isp_scdma;
#ifdef ISP_FW_CRASH_DUMP
/*
* This is only present in channel zero's fcparam
*/
uint16_t * isp_dump_data;
#endif
} fcparam;
@@ -483,30 +516,29 @@ struct ispsoftc {
*/
void * isp_param; /* type specific */
uint16_t isp_fwrev[3]; /* runnng F/W revision */
uint16_t isp_fwrev[3]; /* Loaded F/W revision */
uint16_t isp_maxcmds; /* max possible I/O cmds */
uint8_t isp_type; /* HBA Chip Type */
uint8_t isp_revision; /* HBA Chip H/W Revision */
uint32_t isp_maxluns; /* maximum luns supported */
uint32_t isp_clock : 8, /* input clock */
: 1,
: 4,
isp_port : 1, /* 23XX/24XX only */
isp_failed : 1, /* board failed */
isp_open : 1, /* opened (ioctl) */
isp_bustype : 1, /* SBus or PCI */
isp_loaded_fw : 1, /* loaded firmware */
isp_role : 2, /* roles supported */
isp_dblev : 16; /* debug log mask */
uint32_t isp_confopts; /* config options */
uint16_t isp_fwattr; /* firmware attributes */
uint16_t isp_nchan; /* number of channels */
uint32_t isp_confopts; /* config options */
uint32_t isp_rqstinrp; /* register for REQINP */
uint32_t isp_rqstoutrp; /* register for REQOUTP */
uint32_t isp_respinrp; /* register for RESINP */
uint32_t isp_respoutrp; /* register for RESOUTP */
uint32_t isp_atioinrp; /* register for ATIOINP */
uint32_t isp_atiooutrp; /* register for ATIOOUTP */
/*
* Instrumentation
@@ -525,10 +557,9 @@ struct ispsoftc {
*/
volatile uint32_t : 8,
: 4,
isp_mboxbsy : 1, /* mailbox command active */
isp_state : 3,
isp_sendmarker : 2, /* send a marker entry */
isp_update : 2, /* update parameters */
isp_nactive : 16; /* how many commands active */
volatile uint32_t isp_reqodx; /* index of last ISP pickup */
volatile uint32_t isp_reqidx; /* index of next request */
@@ -552,7 +583,7 @@ struct ispsoftc {
#ifdef ISP_TARGET_MODE
/*
* Active target commands are stored here, indexed by handle function.
* Active target commands are stored here, indexed by handle functions.
*/
void **isp_tgtlist;
#endif
@@ -571,8 +602,20 @@ struct ispsoftc {
#endif
};
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
#define FCPARAM(isp) ((fcparam *) (isp)->isp_param)
#define SDPARAM(isp, chan) (&((sdparam *)(isp)->isp_param)[(chan)])
#define FCPARAM(isp, chan) (&((fcparam *)(isp)->isp_param)[(chan)])
#define ISP_SET_SENDMARKER(isp, chan, val) \
if (IS_FC(isp)) { \
FCPARAM(isp, chan)->sendmarker = val; \
} else { \
SDPARAM(isp, chan)->sendmarker = val; \
}
#define ISP_TST_SENDMARKER(isp, chan) \
(IS_FC(isp)? \
FCPARAM(isp, chan)->sendmarker != 0 : \
SDPARAM(isp, chan)->sendmarker != 0)
/*
* ISP Driver Run States
@@ -596,23 +639,22 @@ struct ispsoftc {
#define ISP_CFG_NPORT 0x04 /* prefer {N/F}-Port connection */
#define ISP_CFG_NPORT_ONLY 0x08 /* insist on {N/F}-Port connection */
#define ISP_CFG_LPORT_ONLY 0x0C /* insist on {N/F}L-Port connection */
#define ISP_CFG_OWNWWPN 0x100 /* override NVRAM wwpn */
#define ISP_CFG_OWNWWNN 0x200 /* override NVRAM wwnn */
#define ISP_CFG_OWNFSZ 0x400 /* override NVRAM frame size */
#define ISP_CFG_OWNLOOPID 0x800 /* override NVRAM loopid */
#define ISP_CFG_OWNEXCTHROTTLE 0x1000 /* override NVRAM execution throttle */
#define ISP_CFG_FOURGB 0x2000 /* force 4GB connection (24XX only) */
/*
* Prior to calling isp_reset for the first time, the outer layer
* should set isp_role to one of NONE, INITIATOR, TARGET, BOTH.
* For each channel, the outer layers should know what role that channel
* will take: ISP_ROLE_NONE, ISP_ROLE_INITIATOR, ISP_ROLE_TARGET,
* ISP_ROLE_BOTH.
*
* If you set ISP_ROLE_NONE, the cards will be reset, new firmware loaded,
* NVRAM read, and defaults set, but any further initialization (e.g.
* INITIALIZE CONTROL BLOCK commands for 2X00 cards) won't be done.
*
* If INITIATOR MODE isn't set, attempts to run commands will be stopped
* at isp_start and completed with the moral equivalent of SELECTION TIMEOUT.
* at isp_start and completed with the equivalent of SELECTION TIMEOUT.
*
* If TARGET MODE is set, it doesn't mean that the rest of target mode support
* needs to be enabled, or will even work. What happens with the 2X00 cards
@@ -782,27 +824,34 @@ void isp_done(XS_T *);
* Platform Dependent to External to Internal Control Function
*
* Assumes locks are held on entry. You should note that with many of
* these commands and locks may be released while this is occurring.
* these commands locks may be released while this function is called.
*
* A few notes about some of these functions:
*
* ISPCTL_FCLINK_TEST tests to make sure we have good fibre channel link.
* The argument is a pointer to an integer which is the time, in microseconds,
* we should wait to see whether we have good link. This test, if successful,
* lets us know our connection topology and our Loop ID/AL_PA and so on.
* You can't get anywhere without this.
*
* ISPCTL_SCAN_FABRIC queries the name server (if we're on a fabric) for
* all entities using the FC Generic Services subcommand GET ALL NEXT.
* For each found entity, an ISPASYNC_FABRICDEV event is generated (see
* below).
*
* ISPCTL_SCAN_LOOP does a local loop scan. This is only done if the connection
* topology is NL or FL port (private or public loop). Since the Qlogic f/w
* 'automatically' manages local loop connections, this function essentially
* notes the arrival, departure, and possible shuffling around of local loop
* entities. Thus for each arrival and departure this generates an isp_async
* event of ISPASYNC_PROMENADE (see below).
* ... ISPCTL_RESET_BUS, int channel);
* Reset BUS on this channel
* ... ISPCTL_RESET_DEV, int channel, int target);
* Reset Device on this channel at this target.
* ... ISPCTL_ABORT_CMD, XS_T *xs);
* Abort active transaction described by xs.
* ... IPCTL_UPDATE_PARAMS);
* Update any operating parameters (speed, etc.)
* ... ISPCTL_FCLINK_TEST, int channel);
* Test FC link status on this channel
* ... ISPCTL_SCAN_FABRIC, int channel);
* Scan fabric on this channel
* ... ISPCTL_SCAN_LOOP, int channel);
* Scan local loop on this channel
* ... ISPCTL_PDB_SYNC, int channel);
* Synchronize port database on this channel
* ... ISPCTL_SEND_LIP, int channel);
* Send a LIP on this channel
* ... ISPCTL_GET_NAMES, int channel, int np, uint64_t *wwnn, uint64_t *wwpn)
* Get a WWNN/WWPN for this N-port handle on this channel
* ... ISPCTL_RUN_MBOXCMD, mbreg_t *mbp)
* Run this mailbox command
* ... ISPCTL_GET_PDB, int channel, int nphandle, isp_pdb_t *pdb)
* Get PDB on this channel for this N-port handle
* ... ISPCTL_PLOGX, isp_plcmd_t *)
* Performa a port login/logout
*
* ISPCTL_PDB_SYNC is somewhat misnamed. It actually is the final step, in
* order, of ISPCTL_FCLINK_TEST, ISPCTL_SCAN_FABRIC, and ISPCTL_SCAN_LOOP.
@@ -813,90 +862,49 @@ void isp_done(XS_T *);
* part of this function. It's now been separated to allow for finer control.
*/
typedef enum {
ISPCTL_RESET_BUS, /* Reset Bus */
ISPCTL_RESET_DEV, /* Reset Device */
ISPCTL_ABORT_CMD, /* Abort Command */
ISPCTL_UPDATE_PARAMS, /* Update Operating Parameters (SCSI) */
ISPCTL_FCLINK_TEST, /* Test FC Link Status */
ISPCTL_SCAN_FABRIC, /* (Re)scan Fabric Name Server */
ISPCTL_SCAN_LOOP, /* (Re)scan Local Loop */
ISPCTL_PDB_SYNC, /* Synchronize Port Database */
ISPCTL_SEND_LIP, /* Send a LIP */
ISPCTL_GET_PORTNAME, /* get portname from an N-port handle */
ISPCTL_GET_NODENAME, /* get nodename from an N-port handle */
ISPCTL_RUN_MBOXCMD, /* run a mailbox command */
ISPCTL_TOGGLE_TMODE, /* toggle target mode */
ISPCTL_GET_PDB, /* get a single port database entry */
ISPCTL_PLOGX /* do a port login/logout */
ISPCTL_RESET_BUS,
ISPCTL_RESET_DEV,
ISPCTL_ABORT_CMD,
ISPCTL_UPDATE_PARAMS,
ISPCTL_FCLINK_TEST,
ISPCTL_SCAN_FABRIC,
ISPCTL_SCAN_LOOP,
ISPCTL_PDB_SYNC,
ISPCTL_SEND_LIP,
ISPCTL_GET_NAMES,
ISPCTL_RUN_MBOXCMD,
ISPCTL_GET_PDB,
ISPCTL_PLOGX
} ispctl_t;
int isp_control(ispsoftc_t *, ispctl_t, void *);
int isp_control(ispsoftc_t *, ispctl_t, ...);
/*
* Platform Dependent to Internal to External Control Function
* (each platform must provide such a function)
*
* Assumes locks are held.
*
* A few notes about some of these functions:
*
* ISPASYNC_CHANGE_NOTIFY notifies the outer layer that a change has
* occurred that invalidates the list of fabric devices known and/or
* the list of known loop devices. The argument passed is a pointer
* whose values are defined below (local loop change, name server
* change, other). 'Other' may simply be a LIP, or a change in
* connection topology.
*
* ISPASYNC_FABRIC_DEV announces the next element in a list of
* fabric device names we're getting out of the name server. The
* argument points to a GET ALL NEXT response structure. The list
* is known to terminate with an entry that refers to ourselves.
* One of the main purposes of this function is to allow outer
* layers, which are OS dependent, to set policy as to which fabric
* devices might actually be logged into (and made visible) later
* at ISPCTL_PDB_SYNC time. Since there's a finite number of fabric
* devices that we can log into (256 less 3 'reserved' for F-port
* topologies), and fabrics can grow up to 8 million or so entries
* (24 bits of Port Address, less a wad of reserved spaces), clearly
* we had better let the OS determine login policy.
*
* ISPASYNC_PROMENADE has an argument that is a pointer to an integer which
* is an index into the portdb in the softc ('target'). Whether that entry's
* valid tag is set or not says whether something has arrived or departed.
* The name refers to a favorite pastime of many city dwellers- watching
* people come and go, talking of Michaelangelo, and so on..
*
* ISPASYNC_UNHANDLED_RESPONSE gives outer layers a chance to parse a
* response queue entry not otherwise handled. The outer layer should
* return non-zero if it handled it. The 'arg' points to an unmassaged
* response queue entry.
*/
typedef enum {
ISPASYNC_NEW_TGT_PARAMS, /* New Target Parameters Negotiated */
ISPASYNC_BUS_RESET, /* Bus Was Reset */
ISPASYNC_NEW_TGT_PARAMS, /* SPI New Target Parameters */
ISPASYNC_BUS_RESET, /* All Bus Was Reset */
ISPASYNC_LOOP_DOWN, /* FC Loop Down */
ISPASYNC_LOOP_UP, /* FC Loop Up */
ISPASYNC_LIP, /* LIP Received */
ISPASYNC_LOOP_RESET, /* Loop Reset Received */
ISPASYNC_LIP, /* FC LIP Received */
ISPASYNC_LOOP_RESET, /* FC Loop Reset Received */
ISPASYNC_CHANGE_NOTIFY, /* FC Change Notification */
ISPASYNC_DEV_ARRIVED, /* FC Device Arrival */
ISPASYNC_DEV_CHANGED, /* FC Device Change */
ISPASYNC_DEV_STAYED, /* FC Device Stayed the Same */
ISPASYNC_DEV_GONE, /* FC Device Depart */
ISPASYNC_TARGET_NOTIFY, /* target asynchronous notification event */
ISPASYNC_TARGET_ACTION, /* target action requested */
ISPASYNC_CONF_CHANGE, /* Platform Configuration Change */
ISPASYNC_UNHANDLED_RESPONSE, /* Unhandled Response Entry */
ISPASYNC_FW_CRASH, /* Firmware has crashed */
ISPASYNC_FW_DUMPED, /* Firmware crashdump taken */
ISPASYNC_FW_RESTARTED /* Firmware has been restarted */
ISPASYNC_DEV_ARRIVED, /* FC Device Arrived */
ISPASYNC_DEV_CHANGED, /* FC Device Changed */
ISPASYNC_DEV_STAYED, /* FC Device Stayed */
ISPASYNC_DEV_GONE, /* FC Device Departure */
ISPASYNC_TARGET_NOTIFY, /* All target async notification */
ISPASYNC_TARGET_ACTION, /* All target action requested */
ISPASYNC_FW_CRASH, /* FC Firmware has crashed */
ISPASYNC_FW_DUMPED, /* FC Firmware crashdump taken */
ISPASYNC_FW_RESTARTED /* FC Firmware has been restarted */
} ispasync_t;
int isp_async(ispsoftc_t *, ispasync_t, void *);
void isp_async(ispsoftc_t *, ispasync_t, ...);
#define ISPASYNC_CHANGE_PDB ((void *) 0)
#define ISPASYNC_CHANGE_SNS ((void *) 1)
#define ISPASYNC_CHANGE_OTHER ((void *) 2)
#define ISPASYNC_CHANGE_PDB 0
#define ISPASYNC_CHANGE_SNS 1
#define ISPASYNC_CHANGE_OTHER 2
/*
* Platform Dependent Error and Debug Printout
@@ -931,7 +939,7 @@ int isp_async(ispsoftc_t *, ispasync_t, void *);
* Each platform must also provide the following macros/defines:
*
*
* ISP2100_SCRLEN - length for the Fibre Channel scratch DMA area
* ISP_FC_SCRLEN FC scratch area DMA length
*
* MEMZERO(dst, src) platform zeroing function
* MEMCPY(dst, src, count) platform copying function
@@ -948,8 +956,7 @@ int isp_async(ispsoftc_t *, ispasync_t, void *);
* NANOTIME_SUB(NANOTIME_T *, NANOTIME_T *)
* subtract two NANOTIME_T values
*
*
* MAXISPREQUEST(ispsoftc_t *) maximum request queue size
* MAXISPREQUEST(ispsoftc_t *) maximum request queue size
* for this particular board type
*
* MEMORYBARRIER(ispsoftc_t *, barrier_type, offset, size)
@@ -963,8 +970,8 @@ int isp_async(ispsoftc_t *, ispasync_t, void *);
* MBOX_NOTIFY_COMPLETE(ispsoftc_t *) notification of mbox cmd donee
* MBOX_RELEASE(ispsoftc_t *) release lock on mailbox regs
*
* FC_SCRATCH_ACQUIRE(ispsoftc_t *) acquire lock on FC scratch area
* FC_SCRATCH_RELEASE(ispsoftc_t *) acquire lock on FC scratch area
* FC_SCRATCH_ACQUIRE(ispsoftc_t *, chan) acquire lock on FC scratch area
* FC_SCRATCH_RELEASE(ispsoftc_t *, chan) acquire lock on FC scratch area
*
* SCSI_GOOD SCSI 'Good' Status
* SCSI_CHECK SCSI 'Check Condition' Status
@@ -1010,28 +1017,31 @@ int isp_async(ispsoftc_t *, ispasync_t, void *);
* response queue entry status bits
*
*
* DEFAULT_IID(ispsoftc_t *) Default SCSI initiator ID
* DEFAULT_LOOPID(ispsoftc_t *) Default FC Loop ID
* DEFAULT_NODEWWN(ispsoftc_t *) Default Node WWN
* DEFAULT_PORTWWN(ispsoftc_t *) Default Port WWN
* DEFAULT_FRAMESIZE(ispsoftc_t *) Default Frame Size
* DEFAULT_EXEC_THROTTLE(ispsoftc_t *) Default Execution Throttle
* DEFAULT_EXEC_THROTTLE(ispsoftc_t *) Default Execution Throttle
*
* GET_DEFAULT_ROLE(ispsoftc_t *, int) Get Default Role for a channel
* SET_DEFAULT_ROLE(ispsoftc_t *, int, int) Set Default Role for a channel
* DEFAULT_IID(ispsoftc_t *, int) Default SCSI initiator ID
* DEFAULT_LOOPID(ispsoftc_t *, int) Default FC Loop ID
*
* These establish reasonable defaults for each platform.
* These must be available independent of card NVRAM and are
* to be used should NVRAM not be readable.
*
* ISP_NODEWWN(ispsoftc_t *) FC Node WWN to use
* ISP_PORTWWN(ispsoftc_t *) FC Port WWN to use
* DEFAULT_NODEWWN(ispsoftc_t *, chan) Default FC Node WWN to use
* DEFAULT_PORTWWN(ispsoftc_t *, chan) Default FC Port WWN to use
*
* These are to be used after NVRAM is read. The tags
* in fcparam.isp_ww{n,p}n_nvram reflect the values
* read from NVRAM (possibly corrected for card botches).
* Each platform can take that information and override
* it or ignore and return the Node and Port WWNs to be
* used when sending the Qlogic f/w the Initialization
* Control Block.
* These defines are hooks to allow the setting of node and
* port WWNs when NVRAM cannot be read or is to be overriden.
*
* ACTIVE_NODEWWN(ispsoftc_t *, chan) FC Node WWN to use
* ACTIVE_PORTWWN(ispsoftc_t *, chan) FC Port WWN to use
*
* After NVRAM is read, these will be invoked to get the
* node and port WWNs that will actually be used for this
* channel.
*
* (XXX these do endian specific transformations- in transition XXX)
*
* ISP_IOXPUT_8(ispsoftc_t *, uint8_t srcval, uint8_t *dstptr)
* ISP_IOXPUT_16(ispsoftc_t *, uint16_t srcval, uint16_t *dstptr)
+12502 -10812
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -54,7 +54,7 @@ tools:
cd ../linux && $(MAKE) tools
tags: FRC
@ctags --recurse --append=no --exclude=Makefile --exclude=freebsd --exclude=solaris ../
@ctags --recurse --append=no --exclude=linux-2.6 --exclude=Makefile --exclude=freebsd --exclude=solaris ../
FRC:
+167 -148
View File
@@ -1,4 +1,4 @@
/* $Id: isp_cb_ops.c,v 1.77 2007/08/29 20:37:08 mjacob Exp $ */
/* $Id: isp_cb_ops.c,v 1.78 2007/12/02 22:02:06 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -61,12 +61,6 @@
#include "isp_ioctl.h"
#include "exioct.h"
#if __GNUC__ >= 4
#define BAD_COMPILER 1
#else
#define BAD_COMPILER 0
#endif
#ifdef CONFIG_PROC_FS
/*
@@ -164,7 +158,9 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
io = len;
} else if (strncmp(buf, "rescan", 6) == 0) {
if (IS_FC(isp)) {
SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, NULL, 1, __FUNCTION__, __LINE__);
for (io = 0; io < isp->isp_nchan; io++) {
ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, io), 1, __FUNCTION__, __LINE__);
}
io = len;
}
} else if (strncmp(buf, "lip", 3) == 0) {
@@ -182,7 +178,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
return (-EINVAL);
}
ISP_LOCKU_SOFTC(isp);
(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
(void) isp_control(isp, ISPCTL_RESET_BUS, bus);
ISP_UNLKU_SOFTC(isp);
io = len;
} else if (strncmp(buf, "devreset=", 9) == 0) {
@@ -194,30 +190,17 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
}
/* always bus 0 */
ISP_LOCKU_SOFTC(isp);
(void) isp_control(isp, ISPCTL_RESET_DEV, &dev);
(void) isp_control(isp, ISPCTL_RESET_DEV, 0, dev);
ISP_UNLKU_SOFTC(isp);
io = len;
} else if (strncmp(buf, "reset", 5) == 0) {
ISP_LOCKU_SOFTC(isp);
io = isp_drain_reset(isp, "proc_reset");
isp_reinit(isp);
ISP_UNLKU_SOFTC(isp);
if (io == 0) {
io = len;
} else {
io = -EIO;
}
} else if (strncmp(buf, "drain", 5) == 0) {
ISP_LOCKU_SOFTC(isp);
io = isp_drain(isp, "proc_reset");
ISP_UNLKU_SOFTC(isp);
if (io == 0) {
io = len;
} else {
io = -EIO;
}
io = len;
} else if (strncmp(buf, "bins", 4) == 0) {
ISP_LOCKU_SOFTC(isp);
memset(isp->isp_osinfo.bins, 0, sizeof (isp->isp_osinfo.bins));
MEMZERO(isp->isp_osinfo.bins, sizeof (isp->isp_osinfo.bins));
ISP_UNLKU_SOFTC(isp);
io = len;
}
@@ -225,7 +208,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
else if (strncmp(buf, "fwcrash", 7) == 0) {
if (IS_FC(isp)) {
ISP_LOCKU_SOFTC(isp);
SEND_THREAD_EVENT(isp, ISP_THREAD_FW_CRASH_DUMP, NULL, 0, __FUNCTION__, __LINE__);
ISP_THREAD_EVENT(isp, ISP_THREAD_FW_CRASH_DUMP, NULL, 0, __FUNCTION__, __LINE__);
ISP_UNLKU_SOFTC(isp);
io = len;
}
@@ -247,7 +230,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
#ifdef HBA_VERSION
copy_info(&info, "\n HBA Version %s, built %s, %s", HBA_VERSION, __DATE__, __TIME__);
#endif
copy_info(&info, "\n DEVID %x role %d\n", isp->isp_osinfo.device_id, isp->isp_role);
copy_info(&info, "\n DEVID %x\n", isp->isp_osinfo.device_id);
copy_info(&info,
" Interrupt Stats:\n"
" total=0x%016llx bogus=0x%016llx\n"
@@ -295,7 +278,7 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
}
copy_info(&info, "\n");
}
copy_info(&info, "blocked %d draining %d qfdelay %d\n", isp->isp_blocked, isp->isp_draining, isp->isp_qfdelay);
// copy_info(&info, "blocked %d qfdelay %d\n", isp->isp_blocked, isp->isp_qfdelay);
copy_info(&info, "\nxfer bins:\n");
copy_info(&info, " <=1024 4096 32768 65536 131072 262144 524288 >0.5M\n");
@@ -313,24 +296,27 @@ isplinux_proc_info(struct Scsi_Host *shp, char *buf, char **st, off_t off, int l
#endif
if (IS_FC(isp)) {
fcparam *fcp = FCPARAM(isp);
copy_info(&info,
"Self:\nHandle ID 0x%x PortID 0x%06x FW State 0x%x Loop State 0x%x\n",
fcp->isp_loopid, fcp->isp_portid, fcp->isp_fwstate, fcp->isp_loopstate);
copy_info(&info, "Port WWN 0x%016llx Node WWN 0x%016llx\n\n", ISP_PORTWWN(isp), ISP_NODEWWN(isp));
copy_info(&info, "FC devices in port database:\n");
for (i = 0; i < MAX_FC_TARG; i++) {
if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) {
continue;
}
if (fcp->portdb[i].ini_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, class3_roles[fcp->portdb[i].roles],
fcp->portdb[i].ini_map_idx - 1, fcp->portdb[i].port_wwn, 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, class3_roles[fcp->portdb[i].roles],
fcp->portdb[i].port_wwn, fcp->portdb[i].node_wwn);
int chan;
for (chan = 0; chan < isp->isp_nchan; chan++) {
fcparam *fcp = FCPARAM(isp, chan);
copy_info(&info,
"Self Channel %d:\nHandle ID 0x%x PortID 0x%06x FW State 0x%x Loop State 0x%x\n", chan,
fcp->isp_loopid, fcp->isp_portid, fcp->isp_fwstate, fcp->isp_loopstate);
copy_info(&info, "Port WWN 0x%016llx Node WWN 0x%016llx\n\n", fcp->isp_wwpn, fcp->isp_wwnn);
copy_info(&info, "FC devices in port database:\n");
for (i = 0; i < MAX_FC_TARG; i++) {
if (fcp->portdb[i].state != FC_PORTDB_STATE_VALID) {
continue;
}
if (fcp->portdb[i].ini_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, fcp->portdb[i].port_wwn, 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],
fcp->portdb[i].port_wwn, fcp->portdb[i].node_wwn);
}
}
}
} else {
@@ -417,9 +403,9 @@ static int
isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
{
ispsoftc_t *isp = fp->private_data;
int rv, inarg, outarg;
int i, rv, inarg, outarg;
fcparam *fcp;
uint16_t loopid;
uint16_t loopid, chan;
mbreg_t mbs;
unsigned long flags;
@@ -531,24 +517,44 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
case ISP_RESCAN:
if (IS_FC(isp)) {
ISP_LOCKU_SOFTC(isp);
SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, NULL, 0, __FUNCTION__, __LINE__)
for (i = 0; i < isp->isp_nchan; i++) {
ISP_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, FCPARAM(isp, i), 1, __FUNCTION__, __LINE__);
}
ISP_UNLKU_SOFTC(isp);
}
break;
case ISP_GETROLE:
outarg = isp->isp_role;
if (COPYIN((void *)arg, &inarg, sizeof (inarg))) {
rv = -EFAULT;
break;
}
chan = inarg >> 16;
if (chan >= isp->isp_nchan) {
rv = -ENXIO;
break;
}
if (IS_FC(isp)) {
outarg = FCPARAM(isp, chan)->role;
} else {
outarg = SDPARAM(isp, chan)->role;
}
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
rv = -EFAULT;
break;
}
break;
case ISP_SETROLE:
if (COPYIN((void *)arg, &inarg, sizeof (inarg))) {
rv = -EFAULT;
break;
}
chan = inarg >> 16;
if (chan >= isp->isp_nchan) {
rv = -ENXIO;
break;
}
inarg &= 0xffff;
if (inarg & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) {
rv = -EINVAL;
break;
@@ -556,37 +562,40 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
/*
* Check to see if we're already in that role.
*/
if (isp->isp_role == inarg) {
outarg = isp->isp_role;
if (IS_FC(isp)) {
if (FCPARAM(isp, chan)->role == inarg) {
break;
}
outarg = FCPARAM(isp, chan)->role;
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
rv = -EFAULT;
break;
}
break;
FCPARAM(isp, chan)->role = inarg;
SET_DEFAULT_ROLE(isp, chan, FCPARAM(isp, chan)->role);
} else {
if (SDPARAM(isp, chan)->role == inarg) {
break;
}
outarg = SDPARAM(isp, chan)->role;
if (COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
rv = -EFAULT;
break;
}
SDPARAM(isp, chan)->role = inarg;
SET_DEFAULT_ROLE(isp, chan, SDPARAM(isp, chan)->role);
}
/*FALLTHROUGH*/
break;
case ISP_RESETHBA:
{
ISP_LOCK_SOFTC(isp);
if (c == ISP_SETROLE) {
outarg = isp->isp_role;
isp->isp_role = inarg;
}
if (isp_drain_reset(isp, "isp_ioctl")) {
ISP_UNLK_SOFTC(isp);
rv = -EIO;
break;
}
isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
isp_reset(isp);
ISP_UNLK_SOFTC(isp);
if (c == ISP_SETROLE && COPYOUT(&outarg, (void *)arg, sizeof (outarg))) {
rv = -EFAULT;
break;
}
break;
}
case ISP_FC_LIP:
ISP_LOCK_SOFTC(isp);
if (isp_control(isp, ISPCTL_SEND_LIP, NULL)) {
if (isp_control(isp, ISPCTL_SEND_LIP, 0)) {
rv = -EIO;
}
ISP_UNLK_SOFTC(isp);
@@ -601,29 +610,32 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
break;
}
if (COPYIN((void *)arg, ifc, sizeof (*ifc))) {
rv = EFAULT;
rv = -EFAULT;
break;
}
if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) {
rv = EINVAL;
if (ifc->chan >= isp->isp_nchan) {
rv = -EINVAL;
break;
}
if (ifc->loopid >= MAX_FC_TARG) {
rv = -EINVAL;
break;
}
ISP_LOCK_SOFTC(isp);
lp = &FCPARAM(isp)->portdb[ifc->loopid];
lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
if (lp->state == FC_PORTDB_STATE_VALID) {
ifc->role = lp->roles;
ifc->loopid = lp->handle;
ifc->portid = lp->portid;
ifc->node_wwn = lp->node_wwn;
ifc->port_wwn = lp->port_wwn;
rv = 0;
} else {
rv = ENODEV;
rv = -ENODEV;
}
ISP_UNLK_SOFTC(isp);
if (rv == 0) {
if (COPYOUT((void *)ifc, (void *)arg, sizeof (*ifc))) {
rv = EFAULT;
rv = -EFAULT;
}
}
break;
@@ -631,22 +643,31 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
case ISP_FC_GETHINFO:
{
struct isp_hba_device local, *hba = &local;
MEMZERO(hba, sizeof (*hba));
if (COPYIN((void *)arg, hba, sizeof (*hba))) {
rv = -EFAULT;
break;
}
chan = hba->fc_channel;
if (chan >= isp->isp_nchan) {
rv = -EINVAL;
break;
}
ISP_LOCK_SOFTC(isp);
hba->fc_nchannels = isp->isp_nchan;
hba->fc_nports = ISP_CAP_2KLOGIN(isp)? 2048 : 256;
hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev);
hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev);
hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev);
hba->fc_speed = FCPARAM(isp)->isp_gbspeed;
hba->fc_scsi_supported = 1;
hba->fc_topology = FCPARAM(isp)->isp_topo + 1;
hba->fc_loopid = FCPARAM(isp)->isp_loopid;
hba->nvram_node_wwn = FCPARAM(isp)->isp_wwnn_nvram;
hba->nvram_port_wwn = FCPARAM(isp)->isp_wwpn_nvram;
hba->active_node_wwn = ISP_NODEWWN(isp);
hba->active_port_wwn = ISP_PORTWWN(isp);
hba->fc_speed = FCPARAM(isp, chan)->isp_gbspeed;
hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1;
hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid;
hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram;
hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram;
hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn;
hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn;
ISP_UNLK_SOFTC(isp);
if (COPYOUT(hba, (void *)arg, sizeof (*hba))) {
rv = EFAULT;
rv = -EFAULT;
break;
}
break;
@@ -657,19 +678,19 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
struct isp_fc_tsk_mgmt local, *fct = (struct isp_fc_tsk_mgmt *) &local;
if (IS_SCSI(isp)) {
rv = EINVAL;
rv = -EINVAL;
break;
}
if (COPYIN((void *)arg, fct, sizeof (*fct))) {
rv = EFAULT;
rv = -EFAULT;
break;
}
MEMZERO(&mbs, sizeof (mbs));
needmarker = rv = 0;
needmarker = 0;
loopid = fct->loopid;
if (FCPARAM(isp)->isp_2klogin == 0) {
if (ISP_CAP_2KLOGIN(isp) == 0) {
loopid <<= 8;
}
switch (fct->action) {
@@ -702,7 +723,7 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
needmarker = 1;
break;
default:
rv = EINVAL;
rv = -EINVAL;
break;
}
if (rv == 0) {
@@ -710,12 +731,12 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
mbs.timeout = 2000000;
ISP_LOCKU_SOFTC(isp);
if (needmarker) {
isp->isp_sendmarker |= 1;
ISP_SET_SENDMARKER(isp, 0, 1);
}
rv = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs);
ISP_UNLKU_SOFTC(isp);
if (rv) {
rv = EIO;
rv = -EIO;
}
}
break;
@@ -723,11 +744,11 @@ 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, lim, count;
uint16_t nph, nphs, nphe, count, chan, lim;
struct wwnpair pair, *uptr;
if (IS_SCSI(isp)) {
rv = EINVAL;
rv = -EINVAL;
break;
}
@@ -735,14 +756,19 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
uptr = &ua->wwns[0];
if (COPYIN((void *)&ua->count, &lim, sizeof (lim))) {
rv = EFAULT;
rv = -EFAULT;
break;
}
if (FCPARAM(isp)->isp_2klogin == 0) {
nphe = NPH_MAX;
} else {
if (COPYIN((void *)&ua->channel, &chan, sizeof (chan))) {
rv = -EFAULT;
break;
}
if (ISP_CAP_2KLOGIN(isp)) {
nphe = NPH_MAX_2K;
} else {
nphe = NPH_MAX;
}
if (IS_24XX(isp)) {
nphs = 1;
@@ -751,38 +777,30 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
}
for (count = 0, nph = nphs; count < lim && nph != nphe; nph++) {
ISP_LOCKU_SOFTC(isp);
pair.wwnn = nph;
if (isp_control(isp, ISPCTL_GET_NODENAME, &pair.wwnn)) {
ISP_UNLKU_SOFTC(isp);
continue;
}
pair.wwpn = nph;
if (isp_control(isp, ISPCTL_GET_PORTNAME, &pair.wwpn)) {
ISP_UNLKU_SOFTC(isp);
continue;
}
rv = isp_control(isp, ISPCTL_GET_NAMES, chan, nph, &pair.wwnn, &pair.wwpn);
ISP_UNLKU_SOFTC(isp);
if (pair.wwnn == 0 || pair.wwpn == 0) {
if (rv || (pair.wwpn == INI_NONE && pair.wwnn == INI_NONE)) {
rv = 0;
continue;
}
count++;
if (COPYOUT(&pair, (void *)uptr++, sizeof (pair))) {
rv = EFAULT;
rv = -EFAULT;
break;
}
count++;
}
if (rv == 0) {
if (COPYOUT(&count, (void *)&ua->count, sizeof (count))) {
rv = EFAULT;
rv = -EFAULT;
}
}
break;
}
default:
rv = EINVAL;
rv = -EINVAL;
break;
}
return(rv? -rv : 0);
return (rv);
}
/*
@@ -792,21 +810,18 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
static int isp_exti_query(EXT_IOCTL *);
static int isp_exti_setinstance(EXT_IOCTL *);
static int isp_exti_fcct_passthru(EXT_IOCTL *);
static int isp_exti_discover_luns(ispsoftc_t *, UINT64, UINT64, UINT16 *);
static int isp_exti_discover_luns(ispsoftc_t *, int, UINT64, UINT64, UINT16 *);
static void *isp_exti_usrptr(UINT64, UINT16);
static int isp_exti_passthru(EXT_IOCTL *);
static int isp_run_cmd(ispsoftc_t *, isp_xcmd_t *);
static int
int
isp_qlogic_ext_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
{
EXT_IOCTL ext;
EXT_IOCTL *uext = (EXT_IOCTL *) arg;
int rval;
if (BAD_COMPILER) {
return (-EINVAL);
}
rval = 0;
if (COPYIN(uext, &ext, sizeof (ext))) {
@@ -849,7 +864,6 @@ isp_qlogic_ext_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsign
ext.Status = EXT_STATUS_UNSUPPORTED_VERSION;
goto out;
}
/*
* We only count FC adapters.
*/
@@ -914,6 +928,7 @@ isp_exti_setinstance(EXT_IOCTL *ext)
}
api_isp = isplist[index];
ext->HbaSelect = api_isp->isp_unit;
api_channel = 0; /* XXXXXXXXXXXXXXXXXXXXXXX */
return (0);
}
@@ -932,9 +947,9 @@ isp_exti_query(EXT_IOCTL *pext)
return (0);
}
ISP_LOCKU_SOFTC(isp);
fcp = FCPARAM(isp);
fcp = FCPARAM(isp, api_channel);
if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate < LOOP_LSCAN_DONE) {
if (isp_fc_runstate(isp, 1000000) < 0) {
if (isp_fc_runstate(isp, api_channel, 1000000) < 0) {
ISP_UNLKU_SOFTC(isp);
pext->Status = EXT_STATUS_PENDING;
return (0);
@@ -971,16 +986,16 @@ isp_exti_query(EXT_IOCTL *pext)
EXT_HBA_PORT hbp;
MEMZERO(&hbp, sizeof (hbp));
MAKE_NODE_NAME_FROM_WWN(hbp.WWPN, ISP_PORTWWN(isp));
MAKE_NODE_NAME_FROM_WWN(hbp.WWPN, FCPARAM(isp, 0)->isp_wwpn);
hbp.Id[1] = (fcp->isp_portid >> 16) & 0xff;
hbp.Id[2] = (fcp->isp_portid >> 8) & 0xff;
hbp.Id[3] = fcp->isp_portid & 0xff;
if (isp->isp_role & ISP_ROLE_TARGET) {
if (FCPARAM(isp, 0)->role & ISP_ROLE_TARGET) {
hbp.Type |= EXT_DEF_TARGET_DEV;
}
if (isp->isp_role & ISP_ROLE_INITIATOR) {
if (FCPARAM(isp, 0)->role & ISP_ROLE_INITIATOR) {
hbp.Type |= EXT_DEF_INITIATOR_DEV;
}
@@ -1015,9 +1030,9 @@ isp_exti_query(EXT_IOCTL *pext)
hbp.PortActiveFC4Types = EXT_DEF_FC4_TYPE_SCSI;
hbp.PortSupportedSpeed = EXT_DEF_PORTSPEED_1GBIT;
if (IS_23XX(isp)) {
hbp.PortSupportedSpeed = EXT_DEF_PORTSPEED_2GBIT;
hbp.PortSupportedSpeed |= EXT_DEF_PORTSPEED_2GBIT;
} else if (IS_24XX(isp)) {
hbp.PortSupportedSpeed = EXT_DEF_PORTSPEED_4GBIT;
hbp.PortSupportedSpeed |= EXT_DEF_PORTSPEED_2GBIT|EXT_DEF_PORTSPEED_4GBIT;
}
cl = min(pext->ResponseLen, sizeof (hbp));
if (COPYOUT(&hbp, outaddr, cl)) {
@@ -1141,7 +1156,7 @@ isp_exti_query(EXT_IOCTL *pext)
wwpn = rlp->port_wwn;
wwnn = rlp->node_wwn;
ISP_UNLKU_SOFTC(isp);
rval = isp_exti_discover_luns(isp, wwpn, wwnn, &tgt.LunCount);
rval = isp_exti_discover_luns(isp, api_channel, wwpn, wwnn, &tgt.LunCount);
if (rval) {
break;
}
@@ -1185,16 +1200,16 @@ isp_exti_query(EXT_IOCTL *pext)
#define IGPOFF 0 /* place CT Request itself is put */
#define OGPOFF (ISP2100_SCRLEN >> 1) /* place CT Response itself is put */
#define ZTXOFF (ISP2100_SCRLEN - (1 * QENTRY_LEN)) /* place where status entry for CT passthru request ends up */
#define CTXOFF (ISP2100_SCRLEN - (2 * QENTRY_LEN)) /* place where CT passthru request is put */
#define OGPOFF (ISP_FC_SCRLEN >> 1) /* place CT Response itself is put */
#define ZTXOFF (ISP_FC_SCRLEN - (1 * QENTRY_LEN)) /* place where status entry for CT passthru request ends up */
#define CTXOFF (ISP_FC_SCRLEN - (2 * QENTRY_LEN)) /* place where CT passthru request is put */
static int
isp_exti_fcct_passthru(EXT_IOCTL *pext)
{
ispsoftc_t *isp = api_isp;
isp_plcmd_t p;
fcparam *fcp = FCPARAM(isp);
fcparam *fcp = FCPARAM(isp, 0);
mbreg_t mbs;
uint8_t qe[QENTRY_LEN], *scp;
uint16_t handle;
@@ -1209,11 +1224,11 @@ isp_exti_fcct_passthru(EXT_IOCTL *pext)
return (0);
}
if (pext->RequestLen > (ISP2100_SCRLEN >> 1)) {
if (pext->RequestLen > (ISP_FC_SCRLEN >> 1)) {
pext->Status = EXT_STATUS_NO_MEMORY;
return (0);
}
if (pext->ResponseLen > ((ISP2100_SCRLEN >> 1) - (2 * QENTRY_LEN))) {
if (pext->ResponseLen > ((ISP_FC_SCRLEN >> 1) - (2 * QENTRY_LEN))) {
pext->Status = EXT_STATUS_NO_MEMORY;
return (0);
}
@@ -1247,6 +1262,7 @@ isp_exti_fcct_passthru(EXT_IOCTL *pext)
/*
* Login into the Management Server
*/
p.channel = api_channel;
p.handle = NIL_HANDLE;
p.portid = MANAGEMENT_PORT_ID;
p.flags = PLOGX_FLG_CMD_PLOGI;
@@ -1263,7 +1279,7 @@ isp_exti_fcct_passthru(EXT_IOCTL *pext)
* Acquire Scratch
*/
MEMZERO(qe, QENTRY_LEN);
FC_SCRATCH_ACQUIRE(isp);
FC_SCRATCH_ACQUIRE(isp, 0);
scp = fcp->isp_scratch;
MEMCPY(&scp[IGPOFF], localmem, pext->RequestLen);
@@ -1328,7 +1344,7 @@ isp_exti_fcct_passthru(EXT_IOCTL *pext)
ms->ms_header.rqs_entry_count = 1;
ms->ms_header.rqs_entry_type = RQSTYPE_MS_PASSTHRU;
ms->ms_handle = 0xffffffff;
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
ms->ms_nphdl = handle;
} else {
ms->ms_nphdl = handle << 8;
@@ -1376,11 +1392,12 @@ out1:
/*
* Release Scratch
*/
FC_SCRATCH_RELEASE(isp);
FC_SCRATCH_RELEASE(isp, 0);
/*
* Log out of the Management Server
*/
p.channel = api_channel;
p.handle = handle;
p.portid = MANAGEMENT_PORT_ID;
p.flags = PLOGX_FLG_CMD_LOGO|PLOGX_FLG_EXPLICIT_LOGO;
@@ -1493,7 +1510,7 @@ isp_exti_passthru(EXT_IOCTL *pext)
MAKE_WWN_FROM_NODE_NAME(wwnn, fcx.FCScsiAddr.DestAddr.WWNN);
} else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWPN) {
MAKE_WWN_FROM_NODE_NAME(wwpn, fcx.FCScsiAddr.DestAddr.WWPN);
} else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_WWNN) {
} else if (fcx.FCScsiAddr.DestType == EXT_DEF_DESTTYPE_PORTID) {
portid = (fcx.FCScsiAddr.DestAddr.Id[1] << 16) | (fcx.FCScsiAddr.DestAddr.Id[2] << 8) | (fcx.FCScsiAddr.DestAddr.Id[3]);
}
/*
@@ -1501,7 +1518,7 @@ isp_exti_passthru(EXT_IOCTL *pext)
* so we know how to send the command.
*/
ISP_LOCKU_SOFTC(isp);
for (lp = &FCPARAM(isp)->portdb[0]; lp < &FCPARAM(isp)->portdb[MAX_FC_TARG]; lp++) {
for (lp = &FCPARAM(isp, api_channel)->portdb[0]; lp < &FCPARAM(isp, api_channel)->portdb[MAX_FC_TARG]; lp++) {
if (lp->state != FC_PORTDB_STATE_VALID) {
continue;
}
@@ -1519,7 +1536,7 @@ isp_exti_passthru(EXT_IOCTL *pext)
}
}
}
if (lp == &FCPARAM(isp)->portdb[MAX_FC_TARG]) {
if (lp == &FCPARAM(isp, api_channel)->portdb[MAX_FC_TARG]) {
ISP_UNLKU_SOFTC(isp);
pext->Status = EXT_STATUS_DEV_NOT_FOUND;
if (bufp) {
@@ -1531,6 +1548,7 @@ isp_exti_passthru(EXT_IOCTL *pext)
wwpn = lp->port_wwn;
cmd.handle = lp->handle;
cmd.portid = lp->portid;
cmd.channel = api_channel;
ISP_UNLKU_SOFTC(isp);
MEMCPY(cmd.fcd.beg.cdb, fcx.Cdb, min(EXT_DEF_SCSI_PASSTHRU_CDB_LENGTH, sizeof (cmd.fcd.beg.cdb)));
@@ -1572,17 +1590,18 @@ isp_exti_passthru(EXT_IOCTL *pext)
#define RPT_LUN_SIZE 1024
static int
isp_exti_discover_luns(ispsoftc_t *isp, UINT64 wwpn, UINT64 wwnn, UINT16 *nluns)
isp_exti_discover_luns(ispsoftc_t *isp, int chan, UINT64 wwpn, UINT64 wwnn, UINT16 *nluns)
{
isp_xcmd_t cmd;
int status, nent, i, hilun;
unsigned long flags;
fcparam *fcp = FCPARAM(isp, chan);
fcportdb_t *lp;
uint8_t *bufp;
MEMZERO(&cmd, sizeof (isp_xcmd_t));
ISP_LOCKU_SOFTC(isp);
for (lp = &FCPARAM(isp)->portdb[0]; lp < &FCPARAM(isp)->portdb[MAX_FC_TARG]; lp++) {
for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
if (lp->state != FC_PORTDB_STATE_VALID) {
continue;
}
@@ -1590,7 +1609,7 @@ isp_exti_discover_luns(ispsoftc_t *isp, UINT64 wwpn, UINT64 wwnn, UINT16 *nluns)
break;
}
}
if (lp == &FCPARAM(isp)->portdb[MAX_FC_TARG]) {
if (lp == &fcp->portdb[MAX_FC_TARG]) {
ISP_UNLKU_SOFTC(isp);
return (-ENODEV);
}
@@ -1731,10 +1750,10 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd)
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
t2->req_flags = REQFLAG_STAG;
if (FCPARAM(isp)->isp_2klogin) {
if (ISP_CAP_2KLOGIN(isp)) {
((ispreqt2e_t *)reqp)->req_target = cmd->handle;
((ispreqt2e_t *)reqp)->req_scclun = cmd->lun;
} else if (FCPARAM(isp)->isp_sccfw) {
} else if (ISP_CAP_SCCFW(isp)) {
t2->req_target = cmd->handle;
t2->req_scclun = cmd->lun;
} else {
+17 -17
View File
@@ -1,4 +1,4 @@
/* $Id: isp_ioctl.h,v 1.23 2007/07/19 01:58:40 mjacob Exp $ */
/* $Id: isp_ioctl.h,v 1.24 2007/12/02 22:02:06 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -138,7 +138,8 @@ typedef struct {
*/
struct isp_fc_device {
uint32_t loopid; /* 0..255/2048 */
uint32_t : 6,
uint32_t
chan : 6,
role : 2,
portid : 24; /* 24 bit Port ID */
uint64_t node_wwn;
@@ -157,20 +158,17 @@ struct isp_fc_device {
* topology and capabilities.
*/
struct isp_hba_device {
uint32_t
: 8,
: 4,
uint32_t : 8,
fc_speed : 4, /* Gbps */
: 2,
fc_class2 : 1,
fc_ip_supported : 1,
fc_scsi_supported : 1,
: 1,
fc_topology : 3,
fc_loopid : 8;
uint8_t fc_fw_major;
uint8_t fc_fw_minor;
uint8_t fc_fw_micro;
uint8_t reserved;
fc_channel : 8, /* channel selector */
fc_loopid : 16; /* loop id selector */
uint8_t fc_fw_major; /* firmware major version */
uint8_t fc_fw_minor; /* firmware minor version */
uint8_t fc_fw_micro; /* firmware micro version */
uint8_t fc_nchannels; /* number of supported channels */
uint16_t fc_nports; /* number of supported ports */
uint64_t nvram_node_wwn;
uint64_t nvram_port_wwn;
uint64_t active_node_wwn;
@@ -183,7 +181,9 @@ struct isp_hba_device {
#define ISP_TOPO_NPORT 3 /* N-port */
#define ISP_TOPO_FPORT 4 /* F-port */
#define ISP_FC_GETHINFO (ISP_IOC|12)
/* do not use this one any more */
/* #define ISP_FC_GETHINFO (ISP_IOC|12) */
#define ISP_FC_GETHINFO (ISP_IOC|13)
/*
* Set Active WWNN/WWPN
@@ -217,13 +217,13 @@ struct isp_fc_tsk_mgmt {
*/
typedef struct {
uint16_t count;
uint16_t reserved;
uint16_t channel;
struct wwnpair {
uint64_t wwnn;
uint64_t wwpn;
} wwns[1];
} isp_dlist_t;
/* don't recycle 22 */
/* do not recycle 22 */
#define ISP_FC_GETDLIST (ISP_IOC | 23)
/*
* vim:ts=4:sw=4:expandtab
+1299 -884
View File
File diff suppressed because it is too large Load Diff
+156 -171
View File
@@ -1,4 +1,4 @@
/* $Id: isp_linux.h,v 1.143 2007/11/15 18:41:47 mjacob Exp $ */
/* $Id: isp_linux.h,v 1.144 2007/12/02 22:02:06 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -71,8 +71,8 @@
#define KERNEL_VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#error "Only Linux 2.6 kernels are supported with this driver"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,7,0)
#error "Only Linux 2.5/2.6 kernels are supported with this driver"
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
@@ -166,13 +166,13 @@ typedef struct scsi_host_template Scsi_Host_Template;
#define ISP_SBUS_SUPPORTED 0
#endif
#define ISP_PLATFORM_VERSION_MAJOR 6
#define ISP_PLATFORM_VERSION_MINOR 0
#ifndef ISP_NAME
#define ISP_NAME "isp"
#endif
#define ISP_PLATFORM_VERSION_MAJOR 5
#define ISP_PLATFORM_VERSION_MINOR 0
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
@@ -220,6 +220,15 @@ typedef struct scsi_host_template Scsi_Host_Template;
#define u_char unsigned char
typedef u_long vm_offset_t;
/* bit map using 8 bit arrays */
typedef uint8_t isp_bmap_t;
#define _ISP_WIX(isp, ix) (ix >> 3)
#define _ISP_BIX(isp, ix) (1 << (ix & 0x7))
#define ISP_NBPIDX(x) ((x + 7) / 8) /* index width from bits */
#define ISP_BTST(map, ix) (((map)[_ISP_WIX(isp, ix)] & _ISP_BIX(isp, ix)) != 0)
#define ISP_BSET(map, ix) (map)[_ISP_WIX(isp, ix)] |= _ISP_BIX(isp, ix)
#define ISP_BCLR(map, ix) (map)[_ISP_WIX(isp, ix)] &= ~_ISP_BIX(isp, ix)
#ifdef ISP_TARGET_MODE
#include "isp_tpublic.h"
@@ -231,13 +240,6 @@ typedef u_long vm_offset_t;
#define N_NOTIFIES 256
#define DEFAULT_INQSIZE 32
#define WIX(ix) (ix >> 5)
#define BIX(ix) (1 << (ix & 0x1f))
#define LUN_BTST(bmap, ix) ((bmap[WIX(ix)] & BIX(ix)) != 0)
#define LUN_BSET(bmap, ix) bmap[WIX(ix)] |= BIX(ix)
#define LUN_BCLR(bmap, ix) bmap[WIX(ix)] &= ~BIX(ix)
typedef struct isp_notify isp_notify_t;
#define cd_action cd_lreserved[0].shorts[0]
@@ -269,6 +271,7 @@ typedef struct {
} tgt_auxcmd_t;
#define N_TGT_AUX 32
#define ISP_CT_TIMEOUT 120
#endif /* ISP_TARGET_MODE */
typedef struct {
@@ -280,22 +283,27 @@ typedef struct {
ISP_THREAD_LOGOUT,
ISP_THREAD_FINDIID,
ISP_THREAD_TERMINATE,
ISP_THREAD_RESTART_AT7,
ISP_THREAD_FC_PUTBACK,
ISP_THREAD_EXIT=99
} thread_action;
void * arg;
struct semaphore * thread_waiter;
int count;
} isp_thread_action_t;
#define MAX_THREAD_ACTION 32
#define MAX_THREAD_ACTION 128
#define MAX_FC_CHAN 128
#define ISP_HOST2ISP(host) (ispsoftc_t *) host->hostdata
union pstore;
struct isposinfo {
struct Scsi_Host * host;
u32 mcorig; /* original maxcmds */
void *device; /* hardware device structure */
Scsi_Cmnd *wqnext, *wqtail;
Scsi_Cmnd *dqnext, *dqtail;
union pstore *storep;
void * storep;
size_t storep_amt;
size_t param_amt;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *pdp;
#endif
@@ -304,46 +312,41 @@ struct isposinfo {
u16 wqcnt;
u16 wqhiwater;
u16 hiwater;
int role;
struct timer_list timer;
struct timer_list _mbtimer;
struct semaphore _mbox_sem;
struct semaphore _mbox_c_sem;
struct semaphore _fcs_sem;
struct timer_list mbtimer;
struct semaphore mbox_sem;
struct semaphore mbox_c_sem;
struct semaphore fcs_sem;
spinlock_t slock;
unsigned volatile int
_downcnt : 8,
: 2,
_qfdelay : 6,
: 5,
_isopen : 1,
_deadloop : 1,
_draining : 1,
_blocked : 1,
_fcrswdog : 1,
_fcrspend : 1,
_dogactive : 1,
_mboxcmd_done : 1,
_mbox_waiting : 1,
_mbintsok : 1,
_intsok : 1;
void * misc[8]; /* private platform variant usage */
struct task_struct * task_thread;
struct semaphore * task_request;
struct semaphore * task_ctl_sem;
: 20,
dogcnt : 5,
isopen : 1,
task_active : 1,
dogactive : 1,
mboxcmd_done : 1,
mbox_waiting : 1,
mbintsok : 1,
intsok : 1;
u16 frame_size;
u16 exec_throttle;
struct semaphore trq;
struct semaphore tcs;
spinlock_t tlock;
unsigned int nt_actions;
unsigned int device_id;
isp_thread_action_t t_actions[MAX_THREAD_ACTION];
#ifdef ISP_TARGET_MODE
uint32_t rollinfo : 16,
u32 isget : 16,
rstatus : 8,
: 6,
isget : 1,
: 7,
hcb : 1;
struct semaphore tgt_inisem;
struct semaphore * rsemap;
tgt_enalun_t * luns; /* enabled { lun, port } tuples */
struct tmd_cmd * pending_t; /* pending list of commands going upstream */
struct tmd_cmd * waiting_t; /* pending list of commands waiting to be fleshed out */
struct tmd_cmd * tfreelist; /* freelist head */
struct tmd_cmd * bfreelist; /* freelist tail */
struct tmd_cmd * pool; /* pool itself */
@@ -357,75 +360,56 @@ struct isposinfo {
* to manage those commands.
*/
tgt_auxcmd_t auxinfo[N_TGT_AUX];
uint32_t auxbmap[N_TGT_AUX >> 5];
uint8_t inqdata[DEFAULT_INQSIZE];
isp_bmap_t auxbmap[ISP_NBPIDX(N_TGT_AUX)];
u8 inqdata[DEFAULT_INQSIZE];
uint64_t cmds_started;
uint64_t cmds_completed;
struct {
uint32_t portid;
uint32_t nphdl;
uint64_t iid;
#define TM_CS 256
} tgt_cache[TM_CS];
u64 cmds_started;
u64 cmds_completed;
#endif
};
#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 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_pbuf isp_osinfo._pbuf
#define isp_fcrspend isp_osinfo._fcrspend
#define isp_fcrswdog isp_osinfo._fcrswdog
#define isp_qfdelay isp_osinfo._qfdelay
#define isp_blocked isp_osinfo._blocked
#define isp_draining isp_osinfo._draining
#define isp_downcnt isp_osinfo._downcnt
#define isp_isopen isp_osinfo._isopen
#define isp_deadloop isp_osinfo._deadloop
#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 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 SEND_THREAD_EVENT(isp, action, a, dowait, file, line) \
if (isp->isp_osinfo.task_request) { \
unsigned long flags; \
spin_lock_irqsave(&isp->isp_osinfo.tlock, flags); \
if (isp->isp_osinfo.nt_actions >= MAX_THREAD_ACTION) { \
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \
isp_prt(isp, ISP_LOGERR, "thread event overflow"); \
} else if (action == ISP_THREAD_FC_RESCAN && isp->isp_fcrspend) { \
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \
} else { \
DECLARE_MUTEX_LOCKED(sem); \
isp_thread_action_t *tap; \
tap = &isp->isp_osinfo.t_actions[isp->isp_osinfo.nt_actions++]; \
tap->thread_action = action; \
tap->arg = a; \
if (dowait) { \
tap->thread_waiter = &sem; \
} else { \
tap->thread_waiter = 0; \
} \
if (action == ISP_THREAD_FC_RESCAN) { \
isp->isp_fcrspend = 1; \
} \
up(isp->isp_osinfo.task_request); \
if (dowait) { \
isp_prt(isp, ISP_LOGDEBUG1, \
"action %d sent from %s:%d and now waiting on %p", action, file, line, &sem); \
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \
down(&sem); \
isp_prt(isp, ISP_LOGDEBUG1, \
"action %d done from %p", action, &sem); \
} else { \
isp_prt(isp, ISP_LOGDEBUG1, "action %d from %s:%d sent", action, file, line); \
spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \
} \
} \
}
#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) \
sema_init(&(x)->isp_osinfo.trq, 0); \
(x)->isp_osinfo.task_active = 1; \
up(&(x)->isp_osinfo.tcs)
#define ISP_THREAD_WAIT(x) down_interruptible(&(x)->isp_osinfo.trq)
#define ISP_THREAD_EVENT isp_thread_event
#define ISP_THREAD_WAKE(x) up(&(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; \
up(&(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...
@@ -455,11 +439,11 @@ if (isp->isp_osinfo.task_request) { \
* Required Macros/Defines
*/
#if defined(CONFIG_HIGHMEM64G) || defined(CONFIG_X86_64)
#if defined(CONFIG_HIGHMEM64G) || defined(CONFIG_X86_64) /* BOGUS */
#define ISP_DAC_SUPPORTED 1
#endif
#define ISP2100_SCRLEN 0x1000
#define ISP_FC_SCRLEN 0x1000
#define MEMZERO(b, a) memset(b, 0, a)
#define MEMCPY memcpy
@@ -499,7 +483,7 @@ if (isp->isp_osinfo.task_request) { \
isp->mboxcmd_done = 1
#define MBOX_RELEASE(isp) up(&isp->mbox_sem)
#define FC_SCRATCH_ACQUIRE(isp) \
#define FC_SCRATCH_ACQUIRE(isp, chan) \
/* \
* Try and acquire semaphore the easy way first- \
* with our lock already held. \
@@ -516,7 +500,7 @@ if (isp->isp_osinfo.task_request) { \
ISP_IGET_LK_SOFTC(isp); \
}
#define FC_SCRATCH_RELEASE(isp) up(&isp->fcs_sem)
#define FC_SCRATCH_RELEASE(isp, chan) up(&isp->fcs_sem)
#ifndef SCSI_GOOD
@@ -591,14 +575,16 @@ if (isp->isp_osinfo.task_request) { \
#define XS_SET_STATE_STAT(a, b, c)
#define DEFAULT_IID isplinux_default_id
#define DEFAULT_LOOPID isplinux_default_id
#define DEFAULT_NODEWWN(isp) (isp)->isp_defwwnn
#define DEFAULT_PORTWWN(isp) (isp)->isp_defwwpn
#define DEFAULT_FRAME_SIZE(isp) (IS_SCSI(isp)? 0 : isp->isp_osinfo.storep->fibre_scsi.default_frame_size)
#define DEFAULT_EXEC_ALLOC(isp) (IS_SCSI(isp)? 0 : isp->isp_osinfo.storep->fibre_scsi.default_exec_alloc)
#define ISP_NODEWWN(isp) (isp)->isp_actvwwnn
#define ISP_PORTWWN(isp) (isp)->isp_actvwwpn
#define GET_DEFAULT_ROLE isplinux_get_default_role
#define SET_DEFAULT_ROLE isplinux_set_default_role
#define DEFAULT_IID isplinux_get_default_id
#define DEFAULT_LOOPID isplinux_get_default_id
#define DEFAULT_FRAMESIZE(isp) isp->isp_osinfo.frame_size
#define DEFAULT_EXEC_THROTTLE(isp) isp->isp_osinfo.exec_throttle
#define DEFAULT_NODEWWN(isp, chan) isplinux_default_wwn(isp, chan, 0, 1)
#define DEFAULT_PORTWWN(isp, chan) isplinux_default_wwn(isp, chan, 0, 0)
#define ACTIVE_NODEWWN(isp, chan) isplinux_default_wwn(isp, chan, 1, 1)
#define ACTIVE_PORTWWN(isp, chan) isplinux_default_wwn(isp, chan, 1, 0)
#define ISP_IOXPUT_8(isp, s, d) *(d) = s
#define ISP_IOXPUT_16(isp, s, d) *(d) = cpu_to_le16(s)
@@ -655,34 +641,28 @@ void isp_prt(ispsoftc_t *, int level, const char *, ...);
*/
/*
* Parameter storage. The order of tags is important- sdparam && fcp
* must come first because isp->isp_params is set to point there...
* Parameter and platform per-channel storage.
*/
union pstore {
struct {
sdparam _sdp[2]; /* they need to be sequential */
u_char psc_opts[2][MAX_TARGETS];
u_char dutydone;
} parallel_scsi;
struct {
fcparam fcp;
uint64_t def_wwnn;
uint64_t def_wwpn;
uint64_t actv_wwnn;
uint64_t actv_wwpn;
uint16_t default_frame_size;
uint16_t default_exec_throttle;
} fibre_scsi;
};
typedef struct {
uint64_t def_wwnn;
uint64_t def_wwpn;
uint32_t
tgts_tested : 16,
: 10,
fcrswdog : 1,
: 1,
blocked : 1,
deadloop : 1,
role : 2;
unsigned int downcount;
unsigned int qfdelay;
} isp_data;
#define ISP_DATA(isp, chan) (&((isp_data *)((isp)->isp_osinfo.storep))[chan])
#define isp_name isp_osinfo.hbaname
#define isp_host isp_osinfo.host
#define isp_unit isp_osinfo.host->unique_id
#define isp_psco isp_osinfo.storep->parallel_scsi.psc_opts
#define isp_dutydone isp_osinfo.storep->parallel_scsi.dutydone
#define isp_defwwnn isp_osinfo.storep->fibre_scsi.def_wwnn
#define isp_defwwpn isp_osinfo.storep->fibre_scsi.def_wwpn
#define isp_actvwwnn isp_osinfo.storep->fibre_scsi.actv_wwnn
#define isp_actvwwpn isp_osinfo.storep->fibre_scsi.actv_wwpn
/*
* Driver prototypes..
@@ -702,22 +682,25 @@ void isplinux_undo_proc(ispsoftc_t *);
int isplinux_reinit(ispsoftc_t *);
void isplinux_sqd(struct Scsi_Host *, struct scsi_device *);
int isp_drain_reset(ispsoftc_t *, char *);
int isp_drain(ispsoftc_t *, char *);
void 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);
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 *);
static inline uint64_t _isp_microtime_sub(struct timeval *, struct timeval *);
static inline void _isp_usec_delay(unsigned int);
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);
const char *isplinux_info(struct Scsi_Host *);
int isplinux_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int isplinux_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]);
int isplinux_default_id(ispsoftc_t *);
int isplinux_get_default_id(ispsoftc_t *, int);
int isplinux_get_default_role(ispsoftc_t *, int);
void isplinux_set_default_role(ispsoftc_t *, int, int);
uint64_t isplinux_default_wwn(ispsoftc_t *, int, int, int);
/*
* Driver wide data...
@@ -731,17 +714,19 @@ extern int isp_fcduplex;
extern int isp_maxsectors;
extern struct scsi_host_template *isp_template;
extern const char *class3_roles[4];
extern int isp_vports;
extern dev_t isp_dev;
extern struct cdev isp_cdev;
extern struct file_operations isp_ioctl_operations;
extern ISP_CLASS *isp_class;
/*
* This used to be considered bad form, but locking crasp made it more attractive.
* This used to be considered bad form, but locking crap made it more attractive.
*/
#define MAX_ISP 32
extern ispsoftc_t *isplist[MAX_ISP];
extern ispsoftc_t *api_isp;
extern int api_channel;
/*
* Platform private flags
@@ -781,7 +766,7 @@ extern ispsoftc_t *api_isp;
#define _SBSWAP(a, b, c)
#endif
static __inline uint64_t
static inline uint64_t
_isp_microtime_sub(struct timeval *b, struct timeval *a)
{
uint64_t elapsed;
@@ -804,7 +789,7 @@ _isp_microtime_sub(struct timeval *b, struct timeval *a)
return (elapsed * 1000);
}
static __inline void
static inline void
_isp_usec_delay(unsigned int usecs)
{
while (usecs > 1000) {
@@ -815,7 +800,7 @@ _isp_usec_delay(unsigned int usecs)
udelay(usecs);
}
static __inline unsigned long
static inline unsigned long
_usec_to_jiffies(unsigned int usecs)
{
struct timespec lt;
@@ -826,7 +811,7 @@ _usec_to_jiffies(unsigned int usecs)
return (timespec_to_jiffies(&lt));
}
static __inline unsigned long
static inline unsigned long
_jiffies_to_usec(unsigned long jiffies)
{
unsigned long usecs;
@@ -848,7 +833,7 @@ _jiffies_to_usec(unsigned long jiffies)
#define MSG_ORDERED_TAG 0x22
#endif
static __inline int
static inline int
isplinux_tagtype(Scsi_Cmnd *Cmnd)
{
switch (Cmnd->tag) {
@@ -863,7 +848,7 @@ isplinux_tagtype(Scsi_Cmnd *Cmnd)
}
}
static __inline int
static inline int
mbox_acquire(ispsoftc_t *isp)
{
/*
@@ -882,7 +867,7 @@ mbox_acquire(ispsoftc_t *isp)
return (0);
}
static __inline void
static inline void
mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
{
uint32_t lim = mbp->timeout;
@@ -947,11 +932,11 @@ mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
/*
* Note that these allocators aren't interrupt safe
*/
static __inline void * isp_kalloc(size_t, int);
static __inline void isp_kfree(void *, size_t);
static __inline void * isp_kzalloc(size_t, int);
static inline void * isp_kalloc(size_t, int);
static inline void isp_kfree(void *, size_t);
static inline void * isp_kzalloc(size_t, int);
static __inline void *
static inline void *
isp_kalloc(size_t size, int flags)
{
void *ptr;
@@ -963,7 +948,7 @@ isp_kalloc(size_t size, int flags)
return (ptr);
}
static __inline void
static inline void
isp_kfree(void *ptr, size_t size)
{
if (size >= PAGE_SIZE) {
@@ -973,12 +958,12 @@ isp_kfree(void *ptr, size_t size)
}
}
static __inline void *
static inline void *
isp_kzalloc(size_t size, int flags)
{
void *ptr = isp_kalloc(size, flags);
if (ptr != NULL){
memset(ptr, 0, size);
MEMZERO(ptr, size);
}
return (ptr);
}
@@ -1001,8 +986,8 @@ void isp_deinit_target(ispsoftc_t *);
void isp_detach_target(ispsoftc_t *);
int isp_target_async(ispsoftc_t *, int, int);
int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
int isp_enable_lun(ispsoftc_t *, uint16_t, uint64_t, uint16_t);
int isp_disable_lun(ispsoftc_t *, uint16_t, uint64_t, uint16_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;
+124 -83
View File
@@ -1,4 +1,4 @@
/* $Id: isp_pci.c,v 1.144 2007/11/27 17:58:04 mjacob Exp $ */
/* $Id: isp_pci.c,v 1.145 2007/12/02 22:02:06 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -357,7 +357,7 @@ static struct ispmdvec mdvec_2400 = {
/*
* Encapsulating softc... Order of elements is important. The tag
* pci_isp must come first because of multiple structure punning
* (Scsi_Host * == struct isp_pcisoftc * == struct ispsofct *).
* (Scsi_Host == struct isp_pcisoftc == ispsoftc_t).
*/
struct isp_pcisoftc {
ispsoftc_t pci_isp;
@@ -367,7 +367,6 @@ struct isp_pcisoftc {
void * vaddr; /* Mapped Memory Address */
vm_offset_t voff;
vm_offset_t poff[_NREG_BLKS];
union pstore params;
};
/*
@@ -426,8 +425,8 @@ map_isp_io(struct isp_pcisoftc *isp_pci, u_short cmd, vm_offset_t io_base)
void
isplinux_pci_release(struct Scsi_Host *host)
{
ispsoftc_t *isp = (ispsoftc_t *) host->hostdata;
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) host->hostdata;
ispsoftc_t *isp = ISP_HOST2ISP(host);
struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
int i;
pci_disable_device(pcs->pci_dev);
@@ -458,13 +457,25 @@ isplinux_pci_release(struct Scsi_Host *host)
isp->isp_result = NULL;
}
if (IS_FC(isp)) {
if (FCPARAM(isp)->isp_scratch) {
pci_free_consistent(pcs->pci_dev, ISP2100_SCRLEN, FCPARAM(isp)->isp_scratch, FCPARAM(isp)->isp_scdma);
FCPARAM(isp)->isp_scratch = NULL;
for (i = 0; i < isp->isp_nchan; i++) {
fcparam *fcp = FCPARAM(isp, i);
if (fcp->isp_scratch) {
pci_free_consistent(pcs->pci_dev, ISP_FC_SCRLEN, fcp->isp_scratch, fcp->isp_scdma);
fcp->isp_scratch = NULL;
}
}
}
pci_release_regions(pcs->pci_dev);
if (isp->isp_param) {
isp_kfree(isp->isp_param, isp->isp_osinfo.param_amt);
isp->isp_param = NULL;
}
if (isp->isp_osinfo.storep) {
isp_kfree(isp->isp_osinfo.storep, isp->isp_osinfo.storep_amt);
isp->isp_osinfo.storep = NULL;
}
/*
* Pull ourselves off the global list
*/
@@ -512,7 +523,7 @@ isplinux_pci_init_one(struct Scsi_Host *host)
struct pci_dev *pdev;
ispsoftc_t *isp;
isp_pci = (struct isp_pcisoftc *) host->hostdata;
isp_pci = (struct isp_pcisoftc *) ISP_HOST2ISP(host);
pdev = isp_pci->pci_dev;
isp = (ispsoftc_t *) isp_pci;
@@ -544,15 +555,18 @@ isplinux_pci_init_one(struct Scsi_Host *host)
isp_pci->poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
isp_pci->poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
isp->isp_nchan = 1;
switch (pdev->device) {
case PCI_DEVICE_ID_QLOGIC_ISP1020:
break;
case PCI_DEVICE_ID_QLOGIC_ISP1080:
case PCI_DEVICE_ID_QLOGIC_ISP12160:
case PCI_DEVICE_ID_QLOGIC_ISP1240:
isp->isp_nchan = 2;
/* FALLTHROUGH */
case PCI_DEVICE_ID_QLOGIC_ISP1080:
case PCI_DEVICE_ID_QLOGIC_ISP1280:
case PCI_DEVICE_ID_QLOGIC_ISP10160:
case PCI_DEVICE_ID_QLOGIC_ISP12160:
isp_pci->poff[DMA_BLOCK >> _BLK_REG_SHFT] = ISP1080_DMA_REGS_OFF;
break;
case PCI_DEVICE_ID_QLOGIC_ISP2200:
@@ -573,6 +587,7 @@ isplinux_pci_init_one(struct Scsi_Host *host)
case PCI_DEVICE_ID_QLOGIC_ISP2432:
isp->isp_port = PCI_FUNC(pdev->devfn);
isp_pci->poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS2400_OFF;
isp->isp_nchan += isp_vports;
break;
default:
isp_prt(isp, ISP_LOGERR, "Device ID 0x%04x is not a known Qlogic Device", pdev->device);
@@ -658,6 +673,7 @@ isplinux_pci_init_one(struct Scsi_Host *host)
host->io_port = isp_pci->port;
}
host->irq = 0;
host->max_channel = isp->isp_nchan - 1;
isp_pci->pci_isp.isp_revision = rev;
#ifndef ISP_DISABLE_1020_SUPPORT
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020) {
@@ -736,7 +752,22 @@ isplinux_pci_init_one(struct Scsi_Host *host)
}
host->irq = pdev->irq;
isp->isp_param = &isp_pci->params;
/*
* Get parameter area set up
*/
isp->isp_osinfo.storep_amt = sizeof (isp_data) * isp->isp_nchan;
if (IS_FC(isp)) {
isp->isp_osinfo.param_amt = sizeof (fcparam) * isp->isp_nchan;
} else {
isp->isp_osinfo.param_amt = sizeof (sdparam) * isp->isp_nchan;
}
isp->isp_param = isp_kzalloc(isp->isp_osinfo.param_amt, GFP_KERNEL);
isp->isp_osinfo.storep = isp_kzalloc(isp->isp_osinfo.storep_amt, GFP_KERNEL);
if (isp->isp_param == NULL || isp->isp_osinfo.storep == NULL) {
isp_prt(isp, ISP_LOGERR, "unable to allocate data structures");
goto bad;
}
/*
* All PCI QLogic cards really can do full 32 bit PCI transactions,
* at least. But the older cards (1020s) have a 24 bit segment limit
@@ -780,6 +811,14 @@ isplinux_pci_init_one(struct Scsi_Host *host)
CREATE_ISP_DEV(isp);
return (0);
bad:
if (isp->isp_param) {
isp_kfree(isp->isp_param, isp->isp_osinfo.param_amt);
isp->isp_param = NULL;
}
if (isp->isp_osinfo.storep) {
isp_kfree(isp->isp_osinfo.storep, isp->isp_osinfo.storep_amt);
isp->isp_osinfo.storep = NULL;
}
if (host->irq) {
ISP_DISABLE_INTS(isp);
free_irq(host->irq, isp_pci);
@@ -1006,10 +1045,10 @@ isp_pci_rd_reg_2400(ispsoftc_t *isp, int regoff)
case BIU2400_REQOUTP:
case BIU2400_RSPINP:
case BIU2400_RSPOUTP:
case BIU2400_PRI_RQINP:
case BIU2400_PRI_RSPINP:
case BIU2400_PRI_REQINP:
case BIU2400_PRI_REQOUTP:
case BIU2400_ATIO_RSPINP:
case BIU2400_ATIO_REQINP:
case BIU2400_ATIO_RSPOUTP:
case BIU2400_HCCR:
case BIU2400_GPIOD:
case BIU2400_GPIOE:
@@ -1067,10 +1106,10 @@ isp_pci_wr_reg_2400(ispsoftc_t *isp, int regoff, uint32_t val)
case BIU2400_REQOUTP:
case BIU2400_RSPINP:
case BIU2400_RSPOUTP:
case BIU2400_PRI_RQINP:
case BIU2400_PRI_RSPINP:
case BIU2400_PRI_REQINP:
case BIU2400_PRI_REQOUTP:
case BIU2400_ATIO_RSPINP:
case BIU2400_ATIO_REQINP:
case BIU2400_ATIO_RSPOUTP:
case BIU2400_HCCR:
case BIU2400_GPIOD:
case BIU2400_GPIOE:
@@ -1259,6 +1298,8 @@ isp_pci_wr_reg_1080(ispsoftc_t *isp, int regoff, uint32_t val)
static int
isp_pci_mbxdma(ispsoftc_t *isp)
{
fcparam *fcp;
int i;
struct isp_pcisoftc *pcs;
if (isp->isp_xflist) {
@@ -1332,19 +1373,21 @@ isp_pci_mbxdma(ispsoftc_t *isp)
}
if (IS_FC(isp)) {
fcparam *fcp = isp->isp_param;
if (fcp->isp_scratch == NULL) {
dma_addr_t busaddr;
fcp->isp_scratch = pci_alloc_consistent(pcs->pci_dev, ISP2100_SCRLEN, &busaddr);
for (i = 0; i < isp->isp_nchan; i++) {
fcp = FCPARAM(isp, i);
if (fcp->isp_scratch == NULL) {
isp_prt(isp, ISP_LOGERR, "unable to allocate scratch space");
goto bad;
}
fcp->isp_scdma = busaddr;
MEMZERO(fcp->isp_scratch, ISP2100_SCRLEN);
if (fcp->isp_scdma & 0x7) {
isp_prt(isp, ISP_LOGERR, "scratch space not 8 byte aligned");
goto bad;
dma_addr_t busaddr;
fcp->isp_scratch = pci_alloc_consistent(pcs->pci_dev, ISP_FC_SCRLEN, &busaddr);
if (fcp->isp_scratch == NULL) {
isp_prt(isp, ISP_LOGERR, "unable to allocate scratch space");
goto bad;
}
fcp->isp_scdma = busaddr;
MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
if (fcp->isp_scdma & 0x7) {
isp_prt(isp, ISP_LOGERR, "scratch space not 8 byte aligned");
goto bad;
}
}
}
}
@@ -1377,10 +1420,15 @@ bad:
isp->isp_result = NULL;
isp->isp_result_dma = 0;
}
if (IS_FC(isp) && FCPARAM(isp)->isp_scratch) {
pci_free_consistent(pcs->pci_dev, ISP2100_SCRLEN, FCPARAM(isp)->isp_scratch, FCPARAM(isp)->isp_scdma);
FCPARAM(isp)->isp_scratch = NULL;
FCPARAM(isp)->isp_scdma = 0;
if (IS_FC(isp)) {
for (i = 0; i < isp->isp_nchan; i++) {
fcp = FCPARAM(isp, i);
if (fcp->isp_scratch) {
pci_free_consistent(pcs->pci_dev, ISP_FC_SCRLEN, fcp->isp_scratch, fcp->isp_scdma);
fcp->isp_scratch = NULL;
fcp->isp_scdma = 0;
}
}
}
ISP_IGET_LK_SOFTC(isp);
return (1);
@@ -1441,6 +1489,9 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin
isp_prt(isp, ISP_LOGTDEBUG1, ctx, cto->ct_fwhandle, L0LUN_TO_FLATLUN(tmd->cd_lun), (int) cto->ct_iid, cto->ct_flags, cto->ct_status,
cto->ct_scsi_status, cto->ct_resid, "<END>");
isp_put_ctio(isp, cto, qe);
if (cto->ct_flags & CT_CCINCR) {
tmd->cd_flags &= ~CDFL_RESRC_FILL;
}
return (CMD_QUEUED);
}
@@ -1662,6 +1713,9 @@ tdma_mk(ispsoftc_t *isp, tmd_xact_t *xact, ct_entry_t *cto, uint32_t *nxtip, uin
}
*nxtip = nxti;
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);
if (sflags & CT_CCINCR) {
tmd->cd_flags &= ~CDFL_RESRC_FILL;
}
return (CMD_QUEUED);
}
@@ -1729,11 +1783,13 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
if (xact->td_xfrlen == 0) {
cto->ct_header.rqs_entry_count = 1;
cto->ct_header.rqs_seqno = 1;
/* ct_syshandle contains the synchronization handle set by caller */
isp_put_ctio7(isp, cto, qe);
ISP_TDQE(isp, "tdma_mk_2400[no data]", curi, qe);
return (CMD_QUEUED);
}
if (xact->td_xfrlen <= 1024) {
nseg = 0;
} else if (xact->td_xfrlen <= 4096) {
@@ -1752,6 +1808,7 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
nseg = 7;
}
isp->isp_osinfo.bins[nseg]++;
/*
* First, count and map all S/G segments
*
@@ -1818,17 +1875,11 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
cto2->ct_flags |= CT7_NO_DATA|CT7_NO_DATA|CT7_FLAG_MODE1;
cto2->ct_seg_count = 0;
MEMZERO(&cto2->rsp, sizeof (cto2->rsp));
cto2->ct_scsi_status = swd;
if ((swd & 0xff) == SCSI_CHECK && (xact->td_hflags & TDFH_SNSVALID)) {
swd |= CT2_SNSLEN_VALID;
cto2->rsp.m1.ct_resplen = min(TMD_SENSELEN, MAXRESPLEN_24XX);
MEMCPY(cto2->rsp.m1.ct_resp, tmd->cd_sense, cto2->rsp.m1.ct_resplen);
}
if (cto2->ct_resid > 0) {
swd |= CT2_DATA_UNDER;
} else if (cto2->ct_resid < 0) {
swd |= CT2_DATA_OVER;
}
cto2->ct_scsi_status = swd;
#else
cto->ct_flags &= ~CT7_SENDSTATUS;
cto->ct_resid = 0;
@@ -1849,35 +1900,27 @@ tdma_mk_2400(ispsoftc_t *isp, tmd_xact_t *xact, ct7_entry_t *cto, uint32_t *nxti
last_synthetic_count = 0;
last_synthetic_addr = 0;
cto->ct_seg_count = 1;
seg = 1;
for (seg = 0; seg < cto->ct_seg_count; seg++) {
bc = min(sg_dma_len(sg), xfcnt);
addr = sg_dma_address(sg);
#ifdef ISP_DAC_SUPPORTED
cto->rsp.m0.ds.ds_base = LOWD(addr);
cto->rsp.m0.ds.ds_basehi = HIWD(addr);
if (!SAME_4G(addr, bc)) {
isp_prt(isp, ISP_LOGTDEBUG1, "seg0[%d]%x%08x:%u (TRUNC'd)", seg, (uint32_t) HIWD(addr), (uint32_t)LOWD(addr), bc);
cto->rsp.m0.ds.ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr);
addr += cto->rsp.m0.ds.ds_count;
bc -= cto->rsp.m0.ds.ds_count;
last_synthetic_count = bc;
last_synthetic_addr = addr;
} else {
cto->rsp.m0.ds.ds_count = bc;
isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __FUNCTION__, seg,
(unsigned long)cto->rsp.m0.ds.ds_basehi, (unsigned long)cto->rsp.m0.ds.ds_base, bc);
}
#else
cto->rsp.m0.ds.ds_base = addr;
cto->rsp.m0.ds.ds_basehi = 0;
bc = min(sg_dma_len(sg), xfcnt);
addr = sg_dma_address(sg);
cto->rsp.m0.ds.ds_base = LOWD(addr);
cto->rsp.m0.ds.ds_basehi = HIWD(addr);
if (!SAME_4G(addr, bc)) {
isp_prt(isp, ISP_LOGTDEBUG1, "seg0[%d]%x%08x:%u (TRUNC'd)", seg, (uint32_t) HIWD(addr), (uint32_t)LOWD(addr), bc);
cto->rsp.m0.ds.ds_count = (unsigned int) (FOURG_SEG(addr + bc) - addr);
addr += cto->rsp.m0.ds.ds_count;
bc -= cto->rsp.m0.ds.ds_count;
last_synthetic_count = bc;
last_synthetic_addr = addr;
} else {
cto->rsp.m0.ds.ds_count = bc;
isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx:%u", __FUNCTION__, seg, (unsigned long) cto->rsp.m0.ds.ds_base, bc);
#endif
cto->rsp.m0.ct_xfrlen += bc;
xfcnt -= bc;
sg++;
isp_prt(isp, ISP_LOGTDEBUG1, "%s: seg0[%d]%lx%08lx:%u", __FUNCTION__, seg,
(unsigned long)cto->rsp.m0.ds.ds_basehi, (unsigned long)cto->rsp.m0.ds.ds_base, bc);
}
cto->rsp.m0.ct_xfrlen += bc;
xfcnt -= bc;
sg++;
if (seg == nseg && last_synthetic_count == 0) {
@@ -2008,7 +2051,7 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
uint32_t curi, nxti;
uint32_t bc, last_synthetic_count;
long xfcnt; /* must be signed */
int nseg, seg, ovseg, seglim, new_seg_cnt;
int nseg, seg, ovseg, seglim, new_seg_cnt, ccincr = 0;
#ifdef ALLOW_SYNTHETIC_CTIO
ct2_entry_t *cto2 = NULL, ct2;
#endif
@@ -2037,6 +2080,9 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
isp_prt(isp, ISP_LOGTDEBUG1, "[%x] faspost (0x%x)", cto->ct_rxid, tmd->cd_cdb[0]);
}
ISP_TDQE(isp, "tdma_mkfc[no data]", curi, qe);
if (cto->ct_flags & CT2_CCINCR) {
tmd->cd_flags &= ~CDFL_RESRC_FILL;
}
return (CMD_QUEUED);
}
@@ -2129,6 +2175,9 @@ tdma_mkfc(ispsoftc_t *isp, tmd_xact_t *xact, ct2_entry_t *cto, uint32_t *nxtip,
swd |= CT2_DATA_OVER;
}
cto2->rsp.m1.ct_scsi_status = swd;
if (cto2->ct_flags & CT2_CCINCR) {
ccincr = 1;
}
#else
cto->ct_flags &= ~(CT2_SENDSTATUS|CT2_CCINCR|CT2_FASTPOST);
cto->ct_resid = 0;
@@ -2377,6 +2426,9 @@ mbxsync:
}
ISP_TDQE(isp, "tdma_mkfc", isp->isp_reqidx, cto);
*nxtip = nxti;
if (ccincr) {
tmd->cd_flags &= ~CDFL_RESRC_FILL;
}
return (CMD_QUEUED);
}
#endif
@@ -2696,12 +2748,12 @@ mbxsync:
}
if (rq->req_header.rqs_entry_type == RQSTYPE_T3RQS) {
if (FCPARAM(isp)->isp_2klogin)
if (ISP_CAP_2KLOGIN(isp))
isp_put_request_t3e(isp, (ispreqt3e_t *) rq, (ispreqt3e_t *) h);
else
isp_put_request_t3(isp, (ispreqt3_t *) rq, (ispreqt3_t *) h);
} else if (rq->req_header.rqs_entry_type == RQSTYPE_T2RQS) {
if (FCPARAM(isp)->isp_2klogin)
if (ISP_CAP_2KLOGIN(isp))
isp_put_request_t2e(isp, (ispreqt2e_t *) rq, (ispreqt2e_t *) h);
else
isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) h);
@@ -3137,12 +3189,11 @@ isplinux_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pci_disable_device(pdev);
return (-ENOMEM);
}
pci_isp = (struct isp_pcisoftc *) host->hostdata;
pci_isp = (struct isp_pcisoftc *) ISP_HOST2ISP(host);
pci_set_drvdata(pdev, pci_isp);
pci_isp->pci_dev = pdev;
isp = (ispsoftc_t *) pci_isp;
isp->isp_host = host;
isp->isp_osinfo.storep = &pci_isp->params;
isp->isp_osinfo.device = pdev;
host->unique_id = isp_unit_seed++;
sprintf(isp->isp_name, "%s%d", ISP_NAME, isp->isp_unit);
@@ -3180,7 +3231,6 @@ isplinux_pci_remove(struct pci_dev *pdev)
struct isp_pcisoftc *pci_isp = pci_get_drvdata(pdev);
unsigned long flags;
ispsoftc_t *isp;
int i;
struct Scsi_Host *host;
isp = (ispsoftc_t *) pci_isp;
@@ -3190,14 +3240,11 @@ isplinux_pci_remove(struct pci_dev *pdev)
#ifdef ISP_TARGET_MODE
isp_detach_target(isp);
#endif
if (isp->isp_osinfo.task_thread) {
SEND_THREAD_EVENT(isp, ISP_THREAD_EXIT, NULL, 1, __FUNCTION__, __LINE__);
}
ISP_THREAD_KILL(isp);
ISP_LOCKU_SOFTC(isp);
isp_shutdown(isp);
isp->dogactive = 0;
del_timer(&isp->isp_osinfo.timer);
isp->isp_role = ISP_ROLE_NONE;
ISP_DISABLE_INTS(isp);
ISP_UNLKU_SOFTC(isp);
isplinux_pci_release(host);
@@ -3219,12 +3266,6 @@ isplinux_pci_remove(struct pci_dev *pdev)
#endif
scsi_host_put(host);
pci_set_drvdata(pdev, NULL);
for (i = 0; i < MAX_ISP; i++) {
if (isplist[i] == isp) {
isplist[i] = NULL;
break;
}
}
}
static struct pci_driver isplinux_pci_driver = {
+102 -60
View File
@@ -1,4 +1,4 @@
/* $Id: scsi_target.c,v 1.74 2007/11/27 17:57:26 mjacob Exp $ */
/* $Id: scsi_target.c,v 1.75 2007/12/02 22:02:06 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -259,7 +259,7 @@ struct initiator {
};
#define HASH_WIDTH 16
#define INI_HASH_LISTP(busp, ini_id) busp->list[ini_id & (HASH_WIDTH - 1)]
#define INI_HASH_LISTP(busp, chan, ini_id) busp->bchan[chan].list[ini_id & (HASH_WIDTH - 1)]
/*
* We maintain a reasonable cache of large sized (8MB) scatterlists
@@ -303,10 +303,14 @@ typedef struct {
} lun_t;
#define LUN_BLOCK_SHIFT 9
struct bus {
hba_register_t h; /* must be first */
struct bus_chan {
ini_t * list[HASH_WIDTH]; /* hash list of known initiators */
lun_t luns[MAX_LUN]; /* luns */
lun_t luns[MAX_LUN]; /* per-channel lun arrays */
};
struct bus {
hba_register_t h; /* must be first */
struct bus_chan *bchan;
};
#define SDprintk if (scsi_tdebug) printk
@@ -333,12 +337,12 @@ static void scsi_target_read_capacity(tmd_cmd_t *, ini_t *);
static void scsi_target_modesense(tmd_cmd_t *, ini_t *);
static int scsi_target_rdwr(tmd_cmd_t *, ini_t *, int);
static int scsi_target_thread(void *);
static int scsi_alloc_disk(bus_t *, int, int, uint64_t);
static void scsi_free_disk(bus_t *, int);
static int scsi_alloc_disk(bus_t *, int, int, int, uint64_t);
static void scsi_free_disk(bus_t *, int, int);
static int scsi_target_copydata(struct scatterlist *, void *, uint32_t, int);
static int scsi_target_start_user_io(sc_io_t *);
static int scsi_target_end_user_io(sc_io_t *);
static int scsi_target_endis(char *, uint64_t, int, int);
static int scsi_target_endis(char *, uint64_t, int, int, int);
/*
* Local Declarations
@@ -423,7 +427,7 @@ scsi_target_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned
rv = -EFAULT;
break;
}
rv = scsi_target_endis(sc->hba_name_unit, sc->nbytes, sc->lun, (cmd == SC_ENABLE_LUN)?((sc->flags == SC_EF_OVERCOMMIT)? 2 : 1) : 0);
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:
@@ -512,7 +516,7 @@ bus_from_name(char *name)
static __inline ini_t *
ini_from_tmd(bus_t *bp, tmd_cmd_t *tmd)
{
ini_t *ptr = INI_HASH_LISTP(bp, tmd->cd_iid);
ini_t *ptr = INI_HASH_LISTP(bp, tmd->cd_channel, tmd->cd_iid);
if (ptr) {
do {
if (ptr->ini_iid == tmd->cd_iid) {
@@ -543,9 +547,9 @@ bus_from_notify(tmd_notify_t *np)
* Make an initiator structure
*/
static void
add_ini(bus_t *bp, uint64_t iid, ini_t *nptr)
add_ini(bus_t *bp, int chan, uint64_t iid, ini_t *nptr)
{
ini_t **ptrlptr = &INI_HASH_LISTP(bp, iid);
ini_t **ptrlptr = &INI_HASH_LISTP(bp, chan, iid);
nptr->ini_iid = iid;
nptr->ini_bus = (struct bus *) bp;
@@ -714,7 +718,7 @@ scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr)
(*bp->h.r_action)(QIN_TMD_CONT, xact);
return;
}
add_ini(bp, tmd->cd_iid, nptr);
add_ini(bp, tmd->cd_channel, tmd->cd_iid, nptr);
spin_unlock_irqrestore(&scsi_target_lock, flags);
ini = nptr;
/*
@@ -784,8 +788,7 @@ scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr)
len = min(sizeof(vp80data), len);
if (len) {
memcpy(addr, vp80data, len);
snprintf(&buf[4], sizeof (vp80data) - 4, "FERAL_%s%d_LUN%06dSER%s", bp->h.r_name, bp->h.r_inst,
L0LUN_TO_FLATLUN(tmd->cd_lun), SERNO);
snprintf(&buf[4], sizeof (vp80data) - 4, "FERAL0LUN%06dSER%s", L0LUN_TO_FLATLUN(tmd->cd_lun), SERNO);
for (j = 0, i = 4; i < sizeof (vp80data); i++) {
if (j == 0) {
if (buf[i] == 0) {
@@ -831,7 +834,7 @@ scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr)
/*
* If we're not here, say we aren't here.
*/
if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) {
if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) {
((u8 *)addr)[0] = 0x7f;
}
SDprintk2("scsi_target(%s%d): %p (%p) length %d byte0 0x%x\n", bp->h.r_name, bp->h.r_inst, addr, dp, dp->length, ((u8 *)addr)[0]);
@@ -901,7 +904,7 @@ scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr)
spin_lock_irqsave(&scsi_target_lock, flags);
for (nluns = i = 0; i < MAX_LUN; i++) {
lun_t *lp = &bp->luns[i];
lun_t *lp = &bp->bchan[tmd->cd_channel].luns[i];
if (lp->enabled) {
uint8_t *ptr = &rpa[8 + (nluns << 3)];
if (i >= 256) {
@@ -999,7 +1002,7 @@ scsi_target_start_cmd(tmd_cmd_t *tmd, int from_intr)
/*
* Make sure we have a legal and open lun
*/
if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) {
if (L0LUN_TO_FLATLUN(tmd->cd_lun) >= MAX_LUN || bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)].enabled == 0) {
if (from_intr) {
scsi_cmd_sched_restart(tmd, "bad or disabled lun");
return;
@@ -1081,10 +1084,10 @@ doit:
} else {
memset(tmd->cd_sense, 0, TMD_SENSELEN);
}
printk("INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u CHECK (0x%x 0x%x 0x%x)\n", tmd->cd_iid, L0LUN_TO_FLATLUN(tmd->cd_lun),
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]);
} else {
SDprintk("INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u ssts=%x hf 0x%x\n", tmd->cd_iid, L0LUN_TO_FLATLUN(tmd->cd_lun),
SDprintk("%s%d: INI(%#llx)=>LUN %d: [%llx] cdb0=0x%02x tl=%u ssts=%x hf 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_scsi_status, xact->td_hflags);
}
(*bp->h.r_action)(QIN_TMD_CONT, xact);
@@ -1109,7 +1112,7 @@ scsi_target_read_capacity_16(tmd_cmd_t *tmd, ini_t *ini)
return;
}
lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
dp = SGS_SGP(addr);
if (tmd->cd_cdb[14] & 0x1) { /* PMI */
@@ -1169,7 +1172,7 @@ scsi_target_read_capacity(tmd_cmd_t *tmd, ini_t *ini)
return;
}
lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
dp = SGS_SGP(addr);
if (tmd->cd_cdb[8] & 0x1) { /* PMI */
@@ -1221,7 +1224,7 @@ scsi_target_modesense(tmd_cmd_t *tmd, ini_t *ini)
void *addr;
bp = ini->ini_bus;
lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
pgctl = tmd->cd_cdb[2] & MODE_PGCTL_MASK;
page = tmd->cd_cdb[2] & MODE_ALL_PAGES;
@@ -1392,7 +1395,7 @@ scsi_target_rdwr(tmd_cmd_t *tmd, ini_t *ini, int from_intr)
unsigned long flags;
bp = ini->ini_bus;
lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
iswrite = 0;
switch (tmd->cd_cdb[0]) {
@@ -1693,7 +1696,7 @@ scsi_target_ldfree(bus_t *bp, tmd_xact_t *xact, int from_intr)
tmd->cd_flags &= ~CDF_PRIVATE_0;
} else if (tmd->cd_flags & CDF_PRIVATE_1) {
struct scatterlist *dp = tmd->cd_dp;
lun_t *lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lun_t *lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
if (dp == NULL) {
printk(KERN_ERR "scsi_target: LDFREE[%llx] null dp @ line %d\n", tmd->cd_tagval, __LINE__);
@@ -1761,7 +1764,11 @@ scsi_target_handler(qact_e action, void *arg)
switch (action) {
case QOUT_HBA_REG:
{
hba_register_t *hp;
hba_register_t *hp = arg;
/*
* Make sure we can allocate an adequate number of lun structures
*/
spin_lock_irqsave(&scsi_target_lock, flags);
for (bp = busses; bp < &busses[MAX_BUS]; bp++) {
if (bp->h.r_action == NULL) {
@@ -1773,7 +1780,6 @@ scsi_target_handler(qact_e action, void *arg)
printk("scsi_target: cannot register any more SCSI busses\n");
break;
}
hp = arg;
if (hp->r_version != QR_VERSION) {
spin_unlock_irqrestore(&scsi_target_lock, flags);
printk("scsi_target: version mismatch- compiled with %d, got %d\n", QR_VERSION, hp->r_version);
@@ -1781,7 +1787,13 @@ scsi_target_handler(qact_e action, void *arg)
}
bp->h = *hp;
spin_unlock_irqrestore(&scsi_target_lock, flags);
printk("scsi_target: registering %s%d\n", hp->r_name, hp->r_inst);
bp->bchan = scsi_target_kzalloc(bp->h.r_nchannels * sizeof (struct bus_chan), GFP_KERNEL);
if (bp->bchan == NULL) {
memset(&bp->h, 0, sizeof (hba_register_t));
printk("scsi_target: cannot allocate buschan for %s%d\n", hp->r_name, hp->r_inst);
} else {
printk("scsi_target: registering %s%d\n", hp->r_name, hp->r_inst);
}
(hp->r_action)(QIN_HBA_REG, arg);
break;
}
@@ -1834,7 +1846,7 @@ scsi_target_handler(qact_e action, void *arg)
lun_t *lp;
SDprintk("scsi_target: [%llx] data receive done\n", tmd->cd_tagval);
spin_lock_irqsave(&scsi_target_lock, flags);
lp = &bp->luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
lp = &bp->bchan[tmd->cd_channel].luns[L0LUN_TO_FLATLUN(tmd->cd_lun)];
/*
* If we're an overcommit disk we don't complete the command here.
*
@@ -1911,7 +1923,7 @@ scsi_target_handler(qact_e action, void *arg)
}
if (np->nt_ncode == NT_ABORT_TASK) {
tmd_cmd_t *tmd;
lun_t *lp = &bp->luns[np->nt_lun];
lun_t *lp = &bp->bchan[np->nt_channel].luns[np->nt_lun];
int i;
for (i = 0, tmd = p_front; tmd; tmd = tmd->cd_next, i++) {
@@ -1942,7 +1954,7 @@ scsi_target_handler(qact_e action, void *arg)
case QOUT_HBA_UNREG:
{
hba_register_t *hp = arg;
int j;
int j, k;
spin_lock_irqsave(&scsi_target_lock, flags);
for (bp = busses; bp < &busses[MAX_BUS]; bp++) {
@@ -1955,26 +1967,32 @@ scsi_target_handler(qact_e action, void *arg)
}
if (bp == &busses[MAX_BUS]) {
spin_unlock_irqrestore(&scsi_target_lock, flags);
printk(KERN_WARNING "%s: HBA_UNREG cannot find busp)\n", __FUNCTION__);
printk(KERN_WARNING "%s: HBA_UNREG cannot find bus\n", __FUNCTION__);
break;
}
spin_unlock_irqrestore(&scsi_target_lock, flags);
for (j = 0; j < HASH_WIDTH; j++) {
ini_t *nptr = bp->list[j];
while (nptr) {
ini_t *next = nptr->ini_next;
free_sdata_chain(nptr->ini_sdata);
scsi_target_kfree(nptr, sizeof (ini_t));
nptr = next;
for (j = 0; j < bp->h.r_nchannels; j++) {
for (k = 0; k < HASH_WIDTH; k++) {
ini_t *nptr = bp->bchan[j].list[k];
while (nptr) {
ini_t *next = nptr->ini_next;
free_sdata_chain(nptr->ini_sdata);
scsi_target_kfree(nptr, sizeof (ini_t));
nptr = next;
}
}
}
for (j = 0; j < MAX_BUS; j++) {
if (bp->luns[j].enabled) {
printk("scsi_target: %s%d had lun %d enabled\n", bp->h.r_name, bp->h.r_inst, j);
scsi_free_disk(bp, j);
for (j = 0; j < bp->h.r_nchannels; j++) {
for (k = 0; k < MAX_LUN; k++) {
if (bp->bchan[j].luns[k].enabled) {
printk("scsi_target: %s%d chan %d had lun %d enabled\n", bp->h.r_name, bp->h.r_inst, j, k);
scsi_free_disk(bp, j, k);
}
}
}
printk("scsi_target: unregistering %s%d\n", bp->h.r_name, bp->h.r_inst);
scsi_target_kfree(bp->bchan, sizeof (struct bus_chan) * bp->h.r_nchannels);
memset(bp, 0, sizeof (*bp));
printk("scsi_target: unregistering %s%d\n", hp->r_name, hp->r_inst);
(hp->r_action)(QIN_HBA_UNREG, arg);
break;
}
@@ -2043,7 +2061,7 @@ scsi_target_thread(void *arg)
}
static int
scsi_alloc_disk(bus_t *bp, int lun, int overcommit, uint64_t nbytes)
scsi_alloc_disk(bus_t *bp, int chan, int lun, int overcommit, uint64_t nbytes)
{
int i;
lun_t *lp;
@@ -2061,7 +2079,7 @@ scsi_alloc_disk(bus_t *bp, int lun, int overcommit, uint64_t nbytes)
nbytes = rusz;
}
lp = &bp->luns[lun];
lp = &bp->bchan[chan].luns[lun];
lp->nbytes = nbytes;
if (overcommit) {
@@ -2117,14 +2135,14 @@ scsi_alloc_disk(bus_t *bp, int lun, int overcommit, uint64_t nbytes)
return (0);
fail:
scsi_free_disk(bp, lun);
scsi_free_disk(bp, chan, lun);
return (-ENOMEM);
}
static void
scsi_free_disk(bus_t *bp, int lun)
scsi_free_disk(bus_t *bp, int chan, int lun)
{
lun_t *lp = &bp->luns[lun];
lun_t *lp = &bp->bchan[chan].luns[lun];
if (lp->overcommit) {
while (lp->pagelists) {
@@ -2207,11 +2225,15 @@ scsi_target_start_user_io(sc_io_t *sc)
return (-ENXIO);
}
if (sc->channel >= bp->h.r_nchannels) {
SDprintk("%s: bad chan (%d)\n", __FUNCTION__, sc->channel);
return (-EINVAL);
}
if (sc->lun >= MAX_LUN) {
SDprintk("%s: bad lun (%d)\n", __FUNCTION__, sc->lun);
return (-EINVAL);
}
lp = &bp->luns[sc->lun];
lp = &bp->bchan[sc->channel].luns[sc->lun];
SDprintk2("%s: waiting for a R/W IO operation\n", __FUNCTION__);
if (down_interruptible(&lp->sema)) {
@@ -2280,11 +2302,15 @@ scsi_target_end_user_io(sc_io_t *sc)
return (-ENXIO);
}
if (sc->channel >= bp->h.r_nchannels) {
SDprintk("%s: bad chan (%d)\n", __FUNCTION__, sc->channel);
return (-EINVAL);
}
if (sc->lun >= MAX_LUN) {
SDprintk("%s: bad lun (%d)\n", __FUNCTION__, sc->lun);
return (-EINVAL);
}
lp = &bp->luns[sc->lun];
lp = &bp->bchan[sc->channel].luns[sc->lun];
tmd = sc->tag;
xact = &tmd->cd_xact;
SDprintk2("scsi_target: USER->KERN [%llx] %p err %d len %u\n", tmd->cd_tagval, tmd, sc->err, sc->len);
@@ -2332,11 +2358,12 @@ scsi_target_end_user_io(sc_io_t *sc)
}
static int
scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int lun, int en)
scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int chan, int lun, int en)
{
DECLARE_MUTEX_LOCKED(rsem);
unsigned long flags;
enadis_t ec;
info_t info;
lun_t *lp;
bus_t *bp;
int rv, i;
@@ -2353,18 +2380,22 @@ scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int lun, int en)
return (-ENXIO);
}
if (chan < 0 || chan >= bp->h.r_nchannels) {
SDprintk("%s: bad chan (%d)\n", __FUNCTION__, chan);
return (-EINVAL);
}
if (lun < 0 || lun >= MAX_LUN) {
SDprintk("%s: bad lun (%d)\n", __FUNCTION__, lun);
return (-EINVAL);
}
lp = &bp->luns[lun];
lp = &bp->bchan[chan].luns[lun];
if (en) {
if (bp->luns[lun].enabled) {
if (lp->enabled) {
printk("%s: lun %d already enabled\n", __FUNCTION__, lun);
return (-EBUSY);
}
rv = scsi_alloc_disk(bp, lun, en == 2, nbytes);
rv = scsi_alloc_disk(bp, chan, lun, en == 2, nbytes);
if (rv) {
return (rv);
}
@@ -2372,10 +2403,21 @@ scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int lun, int en)
lp->enabled = 0;
}
memset(&info, 0, sizeof (info));
info.i_identity = bp->h.r_identity;
info.i_channel = chan;
(*bp->h.r_action)(QIN_GETINFO, &info);
if (info.i_error) {
return (info.i_error);
}
memset(&ec, 0, sizeof (ec));
ec.en_hba = bp->h.r_identity;
ec.en_tgt = TGT_ANY;
ec.en_lun = lun;
if (bp->h.r_type == R_FC) {
ec.en_lun = LUN_ANY;
} else {
ec.en_lun = lun;
}
ec.en_chan = chan;
ec.en_private = &rsem;
(*bp->h.r_action)(en? QIN_ENABLE : QIN_DISABLE, &ec);
@@ -2383,13 +2425,13 @@ scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int lun, int en)
if (ec.en_error) {
SDprintk("%s: HBA returned %d for %s action\n", __FUNCTION__, ec.en_error, en? "enable" : "disable");
scsi_free_disk(bp, lun);
scsi_free_disk(bp, chan, lun);
return (ec.en_error);
}
spin_lock_irqsave(&scsi_target_lock, flags);
for (i = 0; i < HASH_WIDTH; i++) {
ini_t *ini = bp->list[i];
ini_t *ini = bp->bchan[chan].list[i];
while (ini) {
spin_unlock_irqrestore(&scsi_target_lock, flags);
add_sdata(ini, invchg);
@@ -2400,7 +2442,7 @@ scsi_target_endis(char *hba_name_unit, uint64_t nbytes, int lun, int en)
spin_unlock_irqrestore(&scsi_target_lock, flags);
if (en == 0) {
scsi_free_disk(bp, lun);
scsi_free_disk(bp, chan, lun);
} else {
lp->u_tail = lp->u_front = NULL;
sema_init(&lp->sema, 0);
+9 -7
View File
@@ -1,4 +1,4 @@
/* $Id: scsi_target.h,v 1.27 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: scsi_target.h,v 1.28 2007/12/02 22:02:07 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -63,7 +63,7 @@
* Ioctl Definitions File.
*/
#define _SI ('e' << 8)
#define _SI ('j' << 8)
/*
* Set new debugging level (get previous) (int argument).
@@ -74,10 +74,11 @@
* Enable/Disable lun
*/
typedef struct {
char hba_name_unit[16]; /* e.g., "isp0" */
uint64_t nbytes; /* disk size, in bytes */
uint16_t lun; /* lun to map it to */
uint16_t flags; /* flags */
char hba_name_unit[16]; /* e.g., "isp0" */
uint64_t nbytes; /* disk size, in bytes */
uint16_t lun; /* lun to map it to */
uint8_t channel; /* channel */
uint8_t flags;
} sc_enable_t;
#define SC_EF_OVERCOMMIT 0x01 /* allow overcommit */
@@ -91,7 +92,8 @@ typedef struct {
typedef struct {
char hba_name_unit[16]; /* e.g., "isp0" */
uint16_t lun; /* lun */
uint16_t : 14,
uint8_t channel;
uint8_t : 6,
sync : 1, /* (implied) sync after write */
read : 1; /* read (from target to initiator) flag */
void * tag; /* id tag for this command */
+33 -21
View File
@@ -1,4 +1,4 @@
/* $Id: scsi_target_ctl.c,v 1.19 2007/07/07 23:20:56 mjacob Exp $ */
/* $Id: scsi_target_ctl.c,v 1.20 2007/12/02 22:02:07 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -67,6 +67,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include "scsi_target.h"
@@ -74,8 +75,8 @@
const char usage[] = "usage: %s\n\
scsi_target_ctl debug level\n\
scsi_target_ctl enable hba-name-unit nbytes lun [ overcommit-file ]\n\
scsi_target_ctl disable hba-name-unit lun\n";
scsi_target_ctl enable hba-name-unit channel lun nbytes [ overcommit-file ]\n\
scsi_target_ctl disable hba-name-unit channel lun\n";
static uint64_t szarg(char *);
static void ioloop(int, int, char *, uint16_t);
@@ -102,7 +103,7 @@ main(int a, char **v)
debug = getenv("DEBUG") != NULL;
if (a < 3 || a > 6) {
if (a < 3 || a > 7) {
usage:
fprintf(stderr, usage, progname);
return (1);
@@ -110,29 +111,31 @@ main(int a, char **v)
memset(&x, 0, sizeof (x));
if (strcmp(v[1], "enable") == 0) {
if (a < 5) {
if (a < 6) {
goto usage;
}
action = SC_ENABLE_LUN;
strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit));
x._x.nbytes = szarg(v[3]);
x._x.channel = atoi(v[3]);
x._x.lun = atoi(v[4]);
if (a == 6) {
iofd = open(v[5], O_RDWR);
x._x.nbytes = szarg(v[5]);
if (a == 7) {
iofd = open(v[6], O_RDWR);
if (iofd < 0) {
perror(v[5]);
perror(v[6]);
return (1);
}
dprintf("opened %s to back size 0x%016llx bytes\n", v[5], (unsigned long long) x._x.nbytes);
dprintf("opened %s to back size 0x%016llx bytes\n", v[6], (unsigned long long) x._x.nbytes);
x._x.flags = SC_EF_OVERCOMMIT;
}
} else if (strcmp(v[1], "disable") == 0) {
if (a != 4) {
if (a != 5) {
goto usage;
}
action = SC_DISABLE_LUN;
strncpy(x._x.hba_name_unit, v[2], sizeof (x._x.hba_name_unit));
x._x.lun = atoi(v[3]);
x._x.channel = atoi(v[3]);
x._x.lun = atoi(v[4]);
} else if (strcmp(v[1], "debug") == 0) {
if (a != 3) {
goto usage;
@@ -154,9 +157,16 @@ main(int a, char **v)
return (2);
}
if (action == SC_ENABLE_LUN && iofd != -1) {
ioloop(fd, iofd, x._x.hba_name_unit, x._x.lun);
}
if (action == SC_DEBUG) {
pid_t p = fork();
if (p == 0) {
(void) close(0);
(void) close(1);
(void) close(2);
ioloop(fd, iofd, x._x.hba_name_unit, x._x.lun);
} else if (p < 0) {
perror("fork");
}
} else if (action == SC_DEBUG) {
printf("old debug level: %d; new debug level %d\n", x._y, dd);
}
return (0);
@@ -217,6 +227,8 @@ ioloop(int fd, int iofd, char *hba, uint16_t lun)
int amt;
void *buffer = valloc(4 << 20);
openlog("scsi_target_ctl", LOG_NDELAY|LOG_PID, LOG_DAEMON);
for (;;) {
memset(&sc, 0, sizeof (sc));
strcpy(sc.hba_name_unit, hba);
@@ -227,24 +239,24 @@ ioloop(int fd, int iofd, char *hba, uint16_t lun)
if (errno == EINTR || errno == ENOENT) {
continue;
}
perror("SC_GET_IO");
syslog(LOG_ERR, "SC_GET_IO returned %s", strerror(errno));
break;
}
off = (off_t) sc.off;
if (lseek(iofd, off, SEEK_SET) != off) {
perror("lseek");
syslog(LOG_ERR, "lseek error: %s", strerror(errno));
break;
}
if (sc.read) {
amt = read(iofd, sc.addr, sc.amt);
dprintf(" read %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
syslog(LOG_DEBUG, "read %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
} else {
amt = write(iofd, sc.addr, sc.amt);
dprintf("write %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
syslog(LOG_DEBUG, "write %8u @ offset 0x%016llx returns %d\n", sc.amt, (unsigned long long)sc.off, amt);
if (sc.sync) {
if (fdatasync(iofd) < 0) {
sc.err = errno;
perror("FDATASYNC");
syslog(LOG_ERR, "FDATASYNC: %s", strerror(errno));
}
}
}
@@ -256,7 +268,7 @@ ioloop(int fd, int iofd, char *hba, uint16_t lun)
sc.len = amt;
}
if (ioctl(fd, SC_PUT_IO, &sc) < 0) {
perror("SC_PUT_IO");
syslog(LOG_ERR, "SC_PUT_IO: %s", strerror(errno));
break;
}
}