Synchronize with Feral CVS repository:

Add some code to do special IOCBs (that can just be ignored if they show
up as status IOCBs)- this is for some performance testing infrastructure.

Add some performance testing stuff.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@273 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Stanislaw Gruszka
2008-02-12 10:37:37 +00:00
parent 81e3f89ae0
commit c4b2403ead
4 changed files with 185 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
/* $Id: isp.c,v 1.189 2008/01/04 17:54:54 mjacob Exp $ */
/* $Id: isp.c,v 1.190 2008/01/07 19:07:06 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -5304,7 +5304,8 @@ again:
}
}
if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
if ((sp->req_handle != ISP_SPCL_HANDLE) &&
(sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1)) {
isp_prt(isp, ISP_LOGERR,
"bad request handle %d (type 0x%x)",
sp->req_handle, etype);
@@ -5323,7 +5324,8 @@ again:
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (type 0x%x)",
sp->req_handle, etype);
} else if (ts != RQCS_ABORTED) {
} else if (ts != RQCS_ABORTED &&
sp->req_handle != ISP_SPCL_HANDLE) {
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x (status 0x%x)",
sp->req_handle, ts);

View File

@@ -1,4 +1,4 @@
/* $Id: ispmbox.h,v 1.69 2008/01/04 17:46:10 mjacob Exp $ */
/* $Id: ispmbox.h,v 1.70 2008/01/07 19:07:07 mjacob Exp $ */
/*-
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -285,6 +285,11 @@
*/
#define QENTRY_LEN 64
/*
* Special Internal Handle for IOCBs
*/
#define ISP_SPCL_HANDLE 0xa5dead5a
/*
* Command Structure Definitions
*/
@@ -1618,7 +1623,7 @@ typedef struct {
} els_t;
/*
* A handy package structure for running FC-SCSI commands via RUN IOCB A64.
* A handy package structure for running FC-SCSI commands internally
*/
typedef struct {
uint16_t handle;
@@ -1630,8 +1635,9 @@ typedef struct {
union {
struct {
uint32_t data_length;
uint8_t do_read;
uint8_t pad[3];
uint32_t
no_wait : 1,
do_read : 1;
uint8_t cdb[16];
void *data_ptr;
} beg;

View File

@@ -1,4 +1,4 @@
/* $Id: isp_cb_ops.c,v 1.82 2007/12/29 04:50:47 mjacob Exp $ */
/* $Id: isp_cb_ops.c,v 1.83 2008/01/07 19:07:32 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -399,6 +399,8 @@ isp_close(struct inode *ip, struct file *fp)
return (0);
}
static int isp_tur_test(ispsoftc_t *, isp_turtst_t *);
static int
isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
{
@@ -793,6 +795,17 @@ isp_ioctl(struct inode *ip, struct file *fp, unsigned int c, unsigned long arg)
}
break;
}
case ISP_FC_TURTST:
{
isp_turtst_t local, *tt = &local;
if (COPYIN((void *)arg, tt, sizeof (*tt))) {
rv = -EFAULT;
break;
}
rv = isp_tur_test(isp, tt);
break;
}
default:
rv = -EINVAL;
break;
@@ -1742,6 +1755,7 @@ isp_run_cmd(ispsoftc_t *isp, isp_xcmd_t *cmd)
MEMCPY(t7->req_cdb, cmd->fcd.beg.cdb, min(sizeof (t7->req_cdb), sizeof (cmd->fcd.beg.cdb)));
Cmnd->cmd_len = sizeof(t7->req_cdb);
t7->req_time = time;
t7->req_vpidx = cmd->channel;
} else if (IS_FC(isp)) {
ispreqt2_t *t2 = (ispreqt2_t *) local;
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
@@ -1823,6 +1837,152 @@ out:
isp_kfree(Cmnd, sizeof (Scsi_Cmnd));
return (result);
}
static int
isp_tur_test(ispsoftc_t *isp, isp_turtst_t *tt)
{
struct scsi_device *dev = NULL;
Scsi_Cmnd *Cmnd = NULL;
fcportdb_t *lp;
struct Scsi_Host *host = NULL;
uint32_t nxti, optr, handle;
uint8_t local[QENTRY_LEN];
ispreq_t *reqp = (ispreq_t *) local;
int result = 0, i;
void *qep, *qel = local;
DECLARE_MUTEX_LOCKED(rsem);
unsigned long flags;
if (tt->target < 0 || tt->target >= MAX_FC_TARG) {
return (-ENODEV);
}
if (tt->channel < 0 || tt->channel >= isp->isp_nchan) {
return (-ENODEV);
}
i = FCPARAM(isp, tt->channel)->isp_ini_map[tt->target] - 1;
if (i < 0 || i >= MAX_FC_TARG) {
return (-ENXIO);
}
lp = &FCPARAM(isp, tt->channel)->portdb[i];
if (lp->state != FC_PORTDB_STATE_VALID) {
return (-ENXIO);
}
MEMZERO(local, sizeof (local));
Cmnd = isp_kzalloc(sizeof (Scsi_Cmnd), GFP_KERNEL);
if (Cmnd == NULL) {
return (-ENOMEM);
}
host = isp->isp_osinfo.host;
dev = isp_kzalloc(sizeof (struct scsi_device), GFP_KERNEL);
if (dev == NULL) {
isp_kfree(Cmnd, sizeof (Scsi_Cmnd));
return (-ENOMEM);
}
Cmnd->device = dev;
dev->host = host;
Cmnd->scsi_done = isp_run_cmd_done;
Cmnd->request_buffer = &rsem;
Cmnd->cmd_len = 6;
Cmnd->sc_data_direction = SCSI_DATA_NONE;
reqp->req_header.rqs_entry_count = 1;
if (IS_24XX(isp)) {
ispreqt7_t *t7 = (ispreqt7_t *) local;
reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
t7->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE;
t7->req_nphdl = lp->handle;
t7->req_tidlo = lp->portid;
t7->req_tidhi = lp->portid >> 16;
if (tt->lun > 256) {
t7->req_lun[0] = tt->lun >> 8;
t7->req_lun[0] |= 0x40;
}
t7->req_lun[1] = tt->lun & 0xff;
t7->req_time = 30;
t7->req_seg_count = 0;
t7->req_vpidx = tt->channel;
MEMZERO(t7->req_cdb, sizeof (t7->req_cdb));
} else if (IS_FC(isp)) {
ispreqt2_t *t2 = (ispreqt2_t *) local;
reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
t2->req_flags = REQFLAG_STAG;
if (ISP_CAP_2KLOGIN(isp)) {
((ispreqt2e_t *)reqp)->req_target = lp->handle;
((ispreqt2e_t *)reqp)->req_scclun = tt->lun;
} else if (ISP_CAP_SCCFW(isp)) {
t2->req_target = lp->handle;
t2->req_scclun = tt->lun;
} else {
t2->req_target = lp->handle;
t2->req_lun_trn = tt->lun;
}
MEMZERO(t2->req_cdb, sizeof (t2->req_cdb));
t2->req_time = 30;
} else {
reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
reqp->req_flags = REQFLAG_STAG;
reqp->req_target = tt->target;
reqp->req_target |= (tt->channel << 7);
reqp->req_lun_trn = tt->lun;
reqp->req_cdblen = 6;
MEMZERO(reqp->req_cdb, sizeof (reqp->req_cdb));
reqp->req_time = 30;
}
for (i = 0; i < tt->count; i++) {
ISP_LOCKU_SOFTC(isp);
if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
ISP_UNLKU_SOFTC(isp);
__set_current_state(TASK_UNINTERRUPTIBLE);
(void) schedule_timeout(1);
i -= 1;
continue;
}
if (i == tt->count - 1) {
if (isp_save_xs(isp, Cmnd, &handle)) {
ISP_UNLKU_SOFTC(isp);
isp_prt(isp, ISP_LOGERR, "out of xflist pointers");
result = -ENOMEM;
goto out;
}
} else {
handle = ISP_SPCL_HANDLE;
}
reqp->req_handle = handle;
if (IS_24XX(isp)) {
isp_put_request_t7(isp, qel, qep);
} else if (IS_FC(isp)) {
if (ISP_CAP_2KLOGIN(isp)) {
isp_put_request_t2e(isp, qel, qep);
} else {
isp_put_request_t2(isp, qel, qep);
}
} else {
isp_put_request(isp, qel, qep);
}
ISP_ADD_REQUEST(isp, nxti);
if (handle != ISP_SPCL_HANDLE) {
isp->isp_nactive++;
ISP_UNLKU_SOFTC(isp);
down(&rsem);
ISP_LOCKU_SOFTC(isp);
ISP_DMAFREE(isp, Cmnd, handle);
isp_destroy_handle(isp, handle);
}
ISP_UNLKU_SOFTC(isp);
}
out:
if (dev) {
isp_kfree(dev, sizeof (struct scsi_device));
}
isp_kfree(Cmnd, sizeof (Scsi_Cmnd));
return (result);
}
#endif /* CONFIG_PROC_FS */
/*
* vim:ts=4:sw=4:expandtab

View File

@@ -1,4 +1,4 @@
/* $Id: isp_ioctl.h,v 1.25 2007/12/26 22:38:42 mjacob Exp $ */
/* $Id: isp_ioctl.h,v 1.26 2008/01/07 19:07:32 mjacob Exp $ */
/*
* Copyright (c) 1997-2007 by Matthew Jacob
* All rights reserved.
@@ -230,7 +230,15 @@ typedef struct {
} wwns[1];
} isp_dlist_t;
/* do not recycle 22 */
#define ISP_FC_GETDLIST (ISP_IOC | 23)
/*
* This is a trigger for a performance test.
*/
#define ISP_FC_TURTST (ISP_IOC | 44)
typedef struct {
uint32_t channel, target, lun, count;
} isp_turtst_t;
/*
* vim:ts=4:sw=4:expandtab
*/