Unify handles allocation for initiator and target IOCBs.

I am not sure why this was split long ago, but I see no reason for it.
At this point this unification just slightly reduces memory usage, but
as next step I plan to reuse shared handle space for other IOCB types.
This commit is contained in:
Alexander Motin 2015-12-25 13:03:18 +00:00
parent f051a5b324
commit 970ceb2fd5
7 changed files with 60 additions and 191 deletions

View File

@ -4269,7 +4269,7 @@ int
isp_start(XS_T *xs)
{
ispsoftc_t *isp;
uint32_t handle, cdblen;
uint32_t cdblen;
uint8_t local[QENTRY_LEN];
ispreq_t *reqp;
void *cdbp, *qep;
@ -4565,13 +4565,13 @@ isp_start(XS_T *xs)
*tptr = 0x1999;
}
if (isp_allocate_xs(isp, xs, &handle)) {
/* Whew. Thankfully the same for type 7 requests */
reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
if (reqp->req_handle == 0) {
isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
XS_SETERR(xs, HBA_BOTCH);
return (CMD_EAGAIN);
}
/* Whew. Thankfully the same for type 7 requests */
reqp->req_handle = handle;
/*
* Set up DMA and/or do any platform dependent swizzling of the request entry
@ -4581,7 +4581,7 @@ isp_start(XS_T *xs)
*/
dmaresult = ISP_DMASETUP(isp, xs, reqp);
if (dmaresult != CMD_QUEUED) {
isp_destroy_handle(isp, handle);
isp_destroy_handle(isp, reqp->req_handle);
/*
* dmasetup sets actual error in packet, and
* return what we were given to return.
@ -5310,12 +5310,6 @@ isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t info)
}
}
if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
ISP_MEMZERO(hp, QENTRY_LEN); /* PERF */
last_etype = etype;
continue;
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
uint8_t ts = completion_status & 0xff;

View File

@ -1694,7 +1694,8 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
break;
}
if (isp_allocate_xs_tgt(isp, ccb, &handle)) {
handle = isp_allocate_handle(isp, ccb, ISP_HANDLE_TARGET);
if (handle == 0) {
ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__);
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
isp_free_pcmd(isp, ccb);
@ -1723,7 +1724,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local);
if (dmaresult != CMD_QUEUED) {
isp_destroy_tgt_handle(isp, handle);
isp_destroy_handle(isp, handle);
isp_free_pcmd(isp, ccb);
if (dmaresult == CMD_EAGAIN) {
TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe);
@ -2380,12 +2381,12 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
uint32_t handle, moved_data = 0, data_requested;
handle = ((ct2_entry_t *)arg)->ct_syshandle;
ccb = isp_find_xs_tgt(isp, handle);
ccb = isp_find_xs(isp, handle);
if (ccb == NULL) {
isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
return;
}
isp_destroy_tgt_handle(isp, handle);
isp_destroy_handle(isp, handle);
data_requested = PISP_PCMD(ccb)->datalen;
isp_free_pcmd(isp, ccb);
if (isp->isp_nactive) {
@ -3321,7 +3322,7 @@ isp_loop_dead(ispsoftc_t *isp, int chan)
for (i = 0; i < isp->isp_maxcmds; i++) {
struct ccb_scsiio *xs;
if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) {
if (ISP_H2HT(isp->isp_xflist[i].handle) != ISP_HANDLE_INITIATOR) {
continue;
}
if ((xs = isp->isp_xflist[i].cmd) == NULL) {

View File

@ -247,28 +247,26 @@ isp_send_cmd(ispsoftc_t *isp, void *fqe, void *segp, uint32_t nsegs, uint32_t to
return (CMD_QUEUED);
}
int
isp_allocate_xs(ispsoftc_t *isp, XS_T *xs, uint32_t *handlep)
uint32_t
isp_allocate_handle(ispsoftc_t *isp, void *xs, int type)
{
isp_hdl_t *hdp;
hdp = isp->isp_xffree;
if (hdp == NULL) {
return (-1);
}
if (hdp == NULL)
return (ISP_HANDLE_FREE);
isp->isp_xffree = hdp->cmd;
hdp->cmd = xs;
hdp->handle = (hdp - isp->isp_xflist);
hdp->handle |= (ISP_HANDLE_INITIATOR << ISP_HANDLE_USAGE_SHIFT);
hdp->handle |= (type << ISP_HANDLE_USAGE_SHIFT);
hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
*handlep = hdp->handle;
return (0);
return (hdp->handle);
}
XS_T *
void *
isp_find_xs(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_INI_HANDLE(isp, handle)) {
if (!ISP_VALID_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (NULL);
}
@ -276,7 +274,7 @@ isp_find_xs(ispsoftc_t *isp, uint32_t handle)
}
uint32_t
isp_find_handle(ispsoftc_t *isp, XS_T *xs)
isp_find_handle(ispsoftc_t *isp, void *xs)
{
uint32_t i, foundhdl = ISP_HANDLE_FREE;
@ -292,21 +290,10 @@ isp_find_handle(ispsoftc_t *isp, XS_T *xs)
return (foundhdl);
}
uint32_t
isp_handle_index(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (ISP_BAD_HANDLE_INDEX);
} else {
return (handle & ISP_HANDLE_CMD_MASK);
}
}
void
isp_destroy_handle(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_INI_HANDLE(isp, handle)) {
if (!ISP_VALID_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
} else {
isp->isp_xflist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE;
@ -583,46 +570,41 @@ isp_clear_commands(ispsoftc_t *isp)
#endif
for (tmp = 0; isp->isp_xflist && tmp < isp->isp_maxcmds; tmp++) {
XS_T *xs;
hdp = &isp->isp_xflist[tmp];
if (hdp->handle == ISP_HANDLE_FREE) {
continue;
if (ISP_H2HT(hdp->handle) == ISP_HANDLE_INITIATOR) {
XS_T *xs = hdp->cmd;
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, hdp->handle);
XS_SET_RESID(xs, XS_XFRLEN(xs));
} else {
XS_SET_RESID(xs, 0);
}
hdp->handle = 0;
hdp->cmd = NULL;
XS_SETERR(xs, HBA_BUSRESET);
isp_done(xs);
#ifdef ISP_TARGET_MODE
} else if (ISP_H2HT(hdp->handle) == ISP_HANDLE_TARGET) {
uint8_t local[QENTRY_LEN];
ISP_DMAFREE(isp, hdp->cmd, hdp->handle);
ISP_MEMZERO(local, QENTRY_LEN);
if (IS_24XX(isp)) {
ct7_entry_t *ctio = (ct7_entry_t *) local;
ctio->ct_syshandle = hdp->handle;
ctio->ct_nphdl = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
} else {
ct2_entry_t *ctio = (ct2_entry_t *) local;
ctio->ct_syshandle = hdp->handle;
ctio->ct_status = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
}
isp_async(isp, ISPASYNC_TARGET_ACTION, local);
#endif
}
xs = hdp->cmd;
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, hdp->handle);
XS_SET_RESID(xs, XS_XFRLEN(xs));
} else {
XS_SET_RESID(xs, 0);
}
hdp->handle = 0;
hdp->cmd = NULL;
XS_SETERR(xs, HBA_BUSRESET);
isp_done(xs);
}
#ifdef ISP_TARGET_MODE
for (tmp = 0; isp->isp_tgtlist && tmp < isp->isp_maxcmds; tmp++) {
uint8_t local[QENTRY_LEN];
hdp = &isp->isp_tgtlist[tmp];
if (hdp->handle == ISP_HANDLE_FREE) {
continue;
}
ISP_DMAFREE(isp, hdp->cmd, hdp->handle);
ISP_MEMZERO(local, QENTRY_LEN);
if (IS_24XX(isp)) {
ct7_entry_t *ctio = (ct7_entry_t *) local;
ctio->ct_syshandle = hdp->handle;
ctio->ct_nphdl = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
} else {
ct2_entry_t *ctio = (ct2_entry_t *) local;
ctio->ct_syshandle = hdp->handle;
ctio->ct_status = CT_HBA_RESET;
ctio->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
}
isp_async(isp, ISPASYNC_TARGET_ACTION, local);
}
for (tmp = 0; tmp < isp->isp_nchan; tmp++) {
ISP_MEMZERO(&notify, sizeof (isp_notify_t));
notify.nt_ncode = NT_HBA_RESET;
@ -2223,69 +2205,6 @@ isp_send_tgt_cmd(ispsoftc_t *isp, void *fqe, void *segp, uint32_t nsegs, uint32_
return (CMD_QUEUED);
}
int
isp_allocate_xs_tgt(ispsoftc_t *isp, void *xs, uint32_t *handlep)
{
isp_hdl_t *hdp;
hdp = isp->isp_tgtfree;
if (hdp == NULL) {
return (-1);
}
isp->isp_tgtfree = hdp->cmd;
hdp->cmd = xs;
hdp->handle = (hdp - isp->isp_tgtlist);
hdp->handle |= (ISP_HANDLE_TARGET << ISP_HANDLE_USAGE_SHIFT);
/*
* Target handles for SCSI cards are only 16 bits, so
* sequence number protection will be ommitted.
*/
if (IS_FC(isp)) {
hdp->handle |= (isp->isp_seqno++ << ISP_HANDLE_SEQ_SHIFT);
}
*handlep = hdp->handle;
return (0);
}
void *
isp_find_xs_tgt(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_TGT_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
return (NULL);
}
return (isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd);
}
uint32_t
isp_find_tgt_handle(ispsoftc_t *isp, void *xs)
{
uint32_t i, foundhdl = ISP_HANDLE_FREE;
if (xs != NULL) {
for (i = 0; i < isp->isp_maxcmds; i++) {
if (isp->isp_tgtlist[i].cmd != xs) {
continue;
}
foundhdl = isp->isp_tgtlist[i].handle;
break;
}
}
return (foundhdl);
}
void
isp_destroy_tgt_handle(ispsoftc_t *isp, uint32_t handle)
{
if (!ISP_VALID_TGT_HANDLE(isp, handle)) {
isp_prt(isp, ISP_LOGERR, "%s: bad handle 0x%x", __func__, handle);
} else {
isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].handle = ISP_HANDLE_FREE;
isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)].cmd = isp->isp_tgtfree;
isp->isp_tgtfree = &isp->isp_tgtlist[(handle & ISP_HANDLE_CMD_MASK)];
}
}
#endif
/*

View File

@ -43,10 +43,9 @@ int isp_send_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, i
*
* These handles are associate with a command.
*/
int isp_allocate_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(ispsoftc_t *, uint32_t);
uint32_t isp_allocate_handle(ispsoftc_t *, void *, int);
void *isp_find_xs(ispsoftc_t *, uint32_t);
uint32_t isp_find_handle(ispsoftc_t *, void *);
void isp_destroy_handle(ispsoftc_t *, uint32_t);
/*
@ -162,11 +161,6 @@ void isp_put_fcp_rsp_iu(ispsoftc_t *isp, fcp_rsp_iu_t *, fcp_rsp_iu_t *);
#endif
int isp_send_tgt_cmd(ispsoftc_t *, void *, void *, uint32_t, uint32_t, isp_ddir_t, void *, uint32_t);
int isp_allocate_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);
#endif
int isp_find_pdb_empty(ispsoftc_t *, int, fcportdb_t **);
int isp_find_pdb_by_wwpn(ispsoftc_t *, int, uint64_t, fcportdb_t **);

View File

@ -1684,21 +1684,6 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp->isp_xflist[len].cmd = &isp->isp_xflist[len+1];
}
isp->isp_xffree = isp->isp_xflist;
#ifdef ISP_TARGET_MODE
len = sizeof (isp_hdl_t) * isp->isp_maxcmds;
isp->isp_tgtlist = (isp_hdl_t *) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
if (isp->isp_tgtlist == NULL) {
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
free(isp->isp_xflist, M_DEVBUF);
ISP_LOCK(isp);
isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array");
return (1);
}
for (len = 0; len < isp->isp_maxcmds - 1; len++) {
isp->isp_tgtlist[len].cmd = &isp->isp_tgtlist[len+1];
}
isp->isp_tgtfree = isp->isp_tgtlist;
#endif
/*
* Allocate and map the request and result queues (and ATIO queue
@ -1725,9 +1710,6 @@ isp_pci_mbxdma(ispsoftc_t *isp)
isp_prt(isp, ISP_LOGERR, "cannot create a dma tag for control spaces");
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
ISP_LOCK(isp);
return (1);
}
@ -1737,9 +1719,6 @@ isp_pci_mbxdma(ispsoftc_t *isp)
bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
ISP_LOCK(isp);
return (1);
}
@ -1831,9 +1810,6 @@ isp_pci_mbxdma(ispsoftc_t *isp)
bus_dmamem_free(isp->isp_osinfo.cdmat, base, isp->isp_osinfo.cdmap);
bus_dma_tag_destroy(isp->isp_osinfo.cdmat);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
free(isp->isp_osinfo.pcmd_pool, M_DEVBUF);
isp->isp_rquest = NULL;
ISP_LOCK(isp);

View File

@ -1094,7 +1094,7 @@ isp_handle_ctio2(ispsoftc_t *isp, ct2_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
xs = isp_find_xs(isp, ct->ct_syshandle);
if (xs == NULL) {
pl = ISP_LOGALL;
}
@ -1249,7 +1249,7 @@ isp_handle_ctio7(ispsoftc_t *isp, ct7_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
xs = isp_find_xs(isp, ct->ct_syshandle);
if (xs == NULL) {
pl = ISP_LOGALL;
}

View File

@ -318,18 +318,11 @@ typedef struct {
#define ISP_HANDLE_SEQ_MASK 0xffff0000
#define ISP_HANDLE_SEQ_SHIFT 16
#define ISP_H2SEQ(hdl) ((hdl & ISP_HANDLE_SEQ_MASK) >> ISP_HANDLE_SEQ_SHIFT)
#define ISP_VALID_INI_HANDLE(c, hdl) \
(ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_xflist[hdl & ISP_HANDLE_CMD_MASK].handle))
#ifdef ISP_TARGET_MODE
#define ISP_VALID_TGT_HANDLE(c, hdl) \
(ISP_H2HT(hdl) == ISP_HANDLE_TARGET && (hdl & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
ISP_H2SEQ(hdl) == ISP_H2SEQ((c)->isp_tgtlist[hdl & ISP_HANDLE_CMD_MASK].handle))
#define ISP_VALID_HANDLE(c, hdl) \
(ISP_VALID_INI_HANDLE((c), hdl) || ISP_VALID_TGT_HANDLE((c), hdl))
#else
#define ISP_VALID_HANDLE ISP_VALID_INI_HANDLE
#endif
((ISP_H2HT(hdl) == ISP_HANDLE_INITIATOR || \
ISP_H2HT(hdl) == ISP_HANDLE_TARGET) && \
((hdl) & ISP_HANDLE_CMD_MASK) < (c)->isp_maxcmds && \
(hdl) == ((c)->isp_xflist[(hdl) & ISP_HANDLE_CMD_MASK].handle))
#define ISP_BAD_HANDLE_INDEX 0xffffffff
@ -598,14 +591,6 @@ struct ispsoftc {
isp_hdl_t *isp_xflist;
isp_hdl_t *isp_xffree;
#ifdef ISP_TARGET_MODE
/*
* Active target commands are stored here, indexed by handle functions.
*/
isp_hdl_t *isp_tgtlist;
isp_hdl_t *isp_tgtfree;
#endif
/*
* request/result queue pointers and DMA handles for them.
*/