mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-25 09:32:38 +00:00
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:
+1290
-1040
File diff suppressed because it is too large
Load Diff
+212
-36
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
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, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
case ASYNC_LOOP_DOWN:
|
||||
notify.nt_ncode = NT_LINK_DOWN;
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
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, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
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, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
break;
|
||||
case ASYNC_DEVICE_RESET:
|
||||
notify.nt_ncode = NT_TARGET_RESET;
|
||||
(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
isp_async(isp, ISPASYNC_TARGET_NOTIFY, ¬ify);
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+156
-171
@@ -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(<));
|
||||
}
|
||||
|
||||
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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user