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:
parent
dbca8d97f6
commit
25ebfa5a90
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 **);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user