Store the target handles in a separate list from normal commands. Add a

CTIO fast post routine to handle CTIO completions.

Submitted by:	mjacob
This commit is contained in:
njl 2004-05-24 07:02:25 +00:00
parent dbca8d97f6
commit 25ebfa5a90
6 changed files with 126 additions and 16 deletions

View File

@ -5843,7 +5843,7 @@ void
isp_reinit(struct ispsoftc *isp)
{
XS_T *xs;
u_int16_t handle;
int i;
if (IS_FC(isp)) {
isp_mark_getpdb_all(isp);
@ -5863,11 +5863,13 @@ isp_reinit(struct ispsoftc *isp)
}
isp->isp_nactive = 0;
for (handle = 1; (int) handle <= isp->isp_maxcmds; handle++) {
xs = isp_find_xs(isp, handle);
for (i = 0; i < isp->isp_maxcmds; i++) {
u_int16_t handle;
xs = isp->isp_xflist[i];
if (xs == NULL) {
continue;
}
handle = isp_index_handle(i);
isp_destroy_handle(isp, handle);
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, handle);

View File

@ -545,6 +545,7 @@ static cam_status isp_target_start_ctio(struct ispsoftc *, union ccb *);
static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *);
static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *);
static int isp_handle_platform_ctio(struct ispsoftc *, void *);
static void isp_handle_platform_ctio_fastpost(struct ispsoftc *, u_int32_t);
static int isp_handle_platform_notify_scsi(struct ispsoftc *, in_entry_t *);
static int isp_handle_platform_notify_fc(struct ispsoftc *, in_fcentry_t *);
@ -1272,7 +1273,7 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
hp = &cto->ct_syshandle;
}
if (isp_save_xs(isp, (XS_T *)ccb, hp)) {
if (isp_save_xs_tgt(isp, ccb, hp)) {
xpt_print_path(ccb->ccb_h.path);
printf("No XFLIST pointers for isp_target_start_ctio\n");
return (CAM_RESRC_UNAVAIL);
@ -1297,11 +1298,11 @@ isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb)
case CMD_EAGAIN:
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
isp_destroy_handle(isp, save_handle);
isp_destroy_tgt_handle(isp, save_handle);
return (CAM_RESRC_UNAVAIL);
default:
isp_destroy_handle(isp, save_handle);
isp_destroy_tgt_handle(isp, save_handle);
return (XS_ERR(ccb));
}
}
@ -1637,9 +1638,9 @@ isp_handle_platform_ctio(struct ispsoftc *isp, void *arg)
* CTIO and CTIO2 are close enough....
*/
ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_syshandle);
ccb = isp_find_xs_tgt(isp, ((ct_entry_t *)arg)->ct_syshandle);
KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio"));
isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
isp_destroy_tgt_handle(isp, ((ct_entry_t *)arg)->ct_syshandle);
if (IS_FC(isp)) {
ct2_entry_t *ct = arg;
@ -1734,6 +1735,19 @@ isp_handle_platform_ctio(struct ispsoftc *isp, void *arg)
return (0);
}
static void
isp_handle_platform_ctio_fastpost(struct ispsoftc *isp, u_int32_t token)
{
union ccb *ccb;
ccb = isp_find_xs_tgt(isp, token & 0xffff);
KASSERT((ccb != NULL),
("null ccb in isp_handle_platform_ctio_fastpost"));
isp_destroy_tgt_handle(isp, token & 0xffff);
isp_prt(isp, ISP_LOGTDEBUG1, "CTIOx[%x] fastpost complete",
token & 0xffff);
isp_complete_ctio(ccb);
}
static int
isp_handle_platform_notify_scsi(struct ispsoftc *isp, in_entry_t *inp)
{
@ -3019,6 +3033,15 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
case ISPASYNC_TARGET_EVENT:
{
tmd_event_t *ep = arg;
if (ep->ev_event == ASYNC_CTIO_DONE) {
/*
* ACK the interrupt first
*/
ISP_WRITE(isp, BIU_SEMA, 0);
ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
isp_handle_platform_ctio_fastpost(isp, ep->ev_bus);
break;
}
isp_prt(isp, ISP_LOGALL,
"bus %d event code 0x%x", ep->ev_bus, ep->ev_event);
break;

View File

@ -43,8 +43,8 @@ static INLINE int isp_save_xs(struct ispsoftc *, XS_T *, u_int16_t *);
static INLINE XS_T *isp_find_xs(struct ispsoftc *, u_int16_t);
static INLINE u_int16_t isp_find_handle(struct ispsoftc *, XS_T *);
static INLINE int isp_handle_index(u_int16_t);
static INLINE u_int16_t isp_index_handle(int);
static INLINE void isp_destroy_handle(struct ispsoftc *, u_int16_t);
static INLINE void isp_remove_handle(struct ispsoftc *, XS_T *);
static INLINE int
isp_save_xs(struct ispsoftc *isp, XS_T *xs, u_int16_t *handlep)
@ -100,20 +100,77 @@ isp_handle_index(u_int16_t handle)
return (handle-1);
}
static INLINE u_int16_t
isp_index_handle(int index)
{
return (index+1);
}
static INLINE void
isp_destroy_handle(struct ispsoftc *isp, u_int16_t handle)
{
if (handle > 0 && handle <= (u_int16_t) isp->isp_maxcmds) {
isp->isp_xflist[isp_handle_index(handle)] = NULL;
isp->isp_xflist[handle - 1] = NULL;
}
}
static INLINE void
isp_remove_handle(struct ispsoftc *isp, XS_T *xs)
#ifdef ISP_TARGET_MODE
static INLINE int isp_save_xs_tgt(struct ispsoftc *, void *, u_int16_t *);
static INLINE void *isp_find_xs_tgt(struct ispsoftc *, u_int16_t);
static INLINE void isp_destroy_tgt_handle(struct ispsoftc *, u_int16_t);
static INLINE int
isp_save_xs_tgt(struct ispsoftc *isp, void *xs, u_int16_t *handlep)
{
isp_destroy_handle(isp, isp_find_handle(isp, xs));
int i;
for (i = 0; i < (int) isp->isp_maxcmds; i++) {
if (isp->isp_tgtlist[i] == NULL) {
break;
}
}
if (i == isp->isp_maxcmds) {
return (-1);
}
isp->isp_tgtlist[i] = xs;
*handlep = i+1;
return (0);
}
static INLINE void *
isp_find_xs_tgt(struct ispsoftc *isp, u_int16_t handle)
{
if (handle < 1 || handle > (u_int16_t) isp->isp_maxcmds) {
return (NULL);
} else {
return (isp->isp_tgtlist[handle - 1]);
}
}
static INLINE u_int16_t
isp_find_tgt_handle(struct ispsoftc *isp, void *xs)
{
int i;
if (xs != NULL) {
for (i = 0; i < isp->isp_maxcmds; i++) {
if (isp->isp_tgtlist[i] == xs) {
return ((u_int16_t) i+1);
}
}
}
return (0);
}
static INLINE void
isp_destroy_tgt_handle(struct ispsoftc *isp, u_int16_t handle)
{
if (handle > 0 && handle <= (u_int16_t) isp->isp_maxcmds) {
isp->isp_tgtlist[handle - 1] = NULL;
}
}
#endif
static INLINE int
isp_getrqentry(struct ispsoftc *, u_int16_t *, u_int16_t *, void **);

View File

@ -1113,11 +1113,23 @@ isp_pci_mbxdma(struct ispsoftc *isp)
ISP_LOCK(isp);
return (1);
}
#ifdef ISP_TARGET_MODE
len = sizeof (void **) * isp->isp_maxcmds;
isp->isp_tgtlist = (void **) malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
if (isp->isp_tgtlist == NULL) {
isp_prt(isp, ISP_LOGERR, "cannot alloc tgtlist array");
ISP_LOCK(isp);
return (1);
}
#endif
len = sizeof (bus_dmamap_t) * isp->isp_maxcmds;
pcs->dmaps = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
if (pcs->dmaps == NULL) {
isp_prt(isp, ISP_LOGERR, "can't alloc dma map storage");
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
ISP_LOCK(isp);
return (1);
}
@ -1139,6 +1151,9 @@ isp_pci_mbxdma(struct ispsoftc *isp)
"cannot create a dma tag for control spaces");
free(pcs->dmaps, M_DEVBUF);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
ISP_LOCK(isp);
return (1);
}
@ -1149,6 +1164,9 @@ isp_pci_mbxdma(struct ispsoftc *isp)
"cannot allocate %d bytes of CCB memory", len);
bus_dma_tag_destroy(isp->isp_cdmat);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
free(pcs->dmaps, M_DEVBUF);
ISP_LOCK(isp);
return (1);
@ -1189,6 +1207,9 @@ isp_pci_mbxdma(struct ispsoftc *isp)
bus_dmamem_free(isp->isp_cdmat, base, isp->isp_cdmap);
bus_dma_tag_destroy(isp->isp_cdmat);
free(isp->isp_xflist, M_DEVBUF);
#ifdef ISP_TARGET_MODE
free(isp->isp_tgtlist, M_DEVBUF);
#endif
free(pcs->dmaps, M_DEVBUF);
ISP_LOCK(isp);
isp->isp_rquest = NULL;

View File

@ -882,7 +882,7 @@ isp_handle_ctio(struct ispsoftc *isp, ct_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
xs = isp_find_xs(isp, ct->ct_syshandle);
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
if (xs == NULL)
pl = ISP_LOGALL;
} else {
@ -1042,7 +1042,7 @@ isp_handle_ctio2(struct ispsoftc *isp, ct2_entry_t *ct)
char *fmsg = NULL;
if (ct->ct_syshandle) {
xs = isp_find_xs(isp, ct->ct_syshandle);
xs = isp_find_xs_tgt(isp, ct->ct_syshandle);
if (xs == NULL)
pl = ISP_LOGALL;
} else {

View File

@ -54,7 +54,7 @@
#endif
#define ISP_CORE_VERSION_MAJOR 2
#define ISP_CORE_VERSION_MINOR 7
#define ISP_CORE_VERSION_MINOR 8
/*
* Vector for bus specific code to provide specific services.
@ -426,6 +426,13 @@ typedef struct ispsoftc {
*/
XS_T **isp_xflist;
#ifdef ISP_TARGET_MODE
/*
* Active target commands are stored here, indexed by handle function.
*/
void **isp_tgtlist;
#endif
/*
* request/result queue pointers and DMA handles for them.
*/