More rototilling with target mode in an attemp to get multiple
CCB at a time outstanding reliable. It's not there yet, but this is the direction to go in so might as well commit. So far, multiple at a time CCBs work (see ISP_INTERNAL_TARGET test mode), but it fails if there are more downstream than the SIM wants to handle and SRR is sort of confused when this happens, plus it is not entirely quite clear what one does if a CCB/CTIO fails and you have more in flight (that don't fail, say) and more queued up at the SIM level that haven't been started yet. Some of this is driven because there apparently is no flow control to requeue XPT_CONTINUE_IO requests like there are for XPT_SCSI_IO requests. It is also more driven in that the few target mode periph drivers there are are not really set up for handling pushback- heck most of them don't even check for errors (and what would they really do with them anyway? It's the initiator's problem, really....). The data transfer arithmetic has been worked over again to handle multiple outstanding commands, so you have a notion of what's been moved already as well as what's currently in flight. It turns that this led to uncovering a REPORT_LUNS bug in the ISP_INTERNAL_TARGET code which was sending back 24 bytes of rpl data instead of the specified 16. What happened furthermore here is that sending back 16 bytes and reporting an overrun of 8 bytes made the initiator (running FC-Tape aware f/w) mad enough to request, and keep requesting, another FCP response (I guess it didn't like the answer so kept asking for it again). Sponsored by: Spectralogic MFC after: 1 month
This commit is contained in:
parent
2a72e4b222
commit
94dff77179
File diff suppressed because it is too large
Load Diff
@ -102,7 +102,7 @@ typedef struct {
|
||||
void * next;
|
||||
uint32_t orig_datalen;
|
||||
uint32_t bytes_xfered;
|
||||
uint32_t last_xframt;
|
||||
uint32_t bytes_in_transit;
|
||||
uint32_t tag; /* typically f/w RX_ID */
|
||||
uint32_t lun;
|
||||
uint32_t nphdl;
|
||||
@ -112,6 +112,7 @@ typedef struct {
|
||||
uint16_t oxid; /* wire oxid */
|
||||
uint16_t word3; /* PRLI word3 params */
|
||||
uint16_t ctcnt; /* number of CTIOs currently active */
|
||||
uint8_t seqno; /* CTIO sequence number */
|
||||
uint32_t
|
||||
srr_notify_rcvd : 1,
|
||||
cdb0 : 8,
|
||||
@ -134,6 +135,14 @@ typedef struct {
|
||||
#define ATPD_STATE_LAST_CTIO 4
|
||||
#define ATPD_STATE_PDON 5
|
||||
|
||||
#define ATPD_CCB_OUTSTANDING 16
|
||||
|
||||
#define ATPD_SEQ_MASK 0x7f
|
||||
#define ATPD_SEQ_NOTIFY_CAM 0x80
|
||||
#define ATPD_SET_SEQNO(hdrp, atp) ((isphdr_t *)hdrp)->rqs_seqno &= ~ATPD_SEQ_MASK, ((isphdr_t *)hdrp)->rqs_seqno |= (atp)->seqno
|
||||
#define ATPD_GET_SEQNO(hdrp) (((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_MASK)
|
||||
#define ATPD_GET_NCAM(hdrp) ((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
|
||||
|
||||
typedef union inot_private_data inot_private_data_t;
|
||||
union inot_private_data {
|
||||
inot_private_data_t *next;
|
||||
@ -149,9 +158,11 @@ typedef struct isp_timed_notify_ack {
|
||||
uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
|
||||
} isp_tna_t;
|
||||
|
||||
TAILQ_HEAD(isp_ccbq, ccb_hdr);
|
||||
typedef struct tstate {
|
||||
SLIST_ENTRY(tstate) next;
|
||||
struct cam_path *owner;
|
||||
struct isp_ccbq waitq; /* waiting CCBs */
|
||||
struct ccb_hdr_slist atios;
|
||||
struct ccb_hdr_slist inots;
|
||||
uint32_t hold;
|
||||
@ -179,6 +190,7 @@ struct isp_pcmd {
|
||||
bus_dmamap_t dmap; /* dma map for this command */
|
||||
struct ispsoftc * isp; /* containing isp */
|
||||
struct callout wdog; /* watchdog timer */
|
||||
uint32_t datalen; /* data length for this command (target mode only) */
|
||||
uint8_t totslen; /* sense length on status response */
|
||||
uint8_t cumslen; /* sense length on status response */
|
||||
uint8_t crn; /* command reference number */
|
||||
|
Loading…
Reference in New Issue
Block a user