Date: Wed, 25 Jan 2012 23:33:50 +0000 (UTC) From: Sean Bruno <sbruno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r230558 - head/sys/dev/firewire Message-ID: <201201252333.q0PNXoWK050308@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sbruno Date: Wed Jan 25 23:33:50 2012 New Revision: 230558 URL: http://svn.freebsd.org/changeset/base/230558 Log: Update sbp_targ such that it can actually handle multiple CTIO's during operation PR: kern/119575 Modified: head/sys/dev/firewire/sbp_targ.c Modified: head/sys/dev/firewire/sbp_targ.c ============================================================================== --- head/sys/dev/firewire/sbp_targ.c Wed Jan 25 22:39:22 2012 (r230557) +++ head/sys/dev/firewire/sbp_targ.c Wed Jan 25 23:33:50 2012 (r230558) @@ -62,6 +62,7 @@ #include <cam/cam_debug.h> #include <cam/cam_periph.h> #include <cam/scsi/scsi_all.h> +#include <cam/scsi/scsi_message.h> #define SBP_TARG_RECV_LEN 8 #define MAX_INITIATORS 8 @@ -186,6 +187,21 @@ struct morb4 { #endif }; + +/* + * Urestricted page table format + * states that the segment length + * and high base addr are in the first + * 32 bits and the base low is in + * the second + */ +struct unrestricted_page_table_fmt { + uint16_t segment_len; + uint16_t segment_base_high; + uint32_t segment_base_low; +}; + + struct orb_info { struct sbp_targ_softc *sc; struct fw_device *fwdev; @@ -208,7 +224,10 @@ struct orb_info { struct corb4 orb4; STAILQ_ENTRY(orb_info) link; uint32_t orb[8]; - uint32_t *page_table; + struct unrestricted_page_table_fmt *page_table; + struct unrestricted_page_table_fmt *cur_pte; + struct unrestricted_page_table_fmt *last_pte; + uint32_t last_block_read; struct sbp_status status; }; @@ -219,6 +238,7 @@ static char *orb_fun_name[] = { static void sbp_targ_recv(struct fw_xfer *); static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *, uint16_t, uint32_t, struct sbp_targ_login *, int); +static void sbp_targ_xfer_pt(struct orb_info *); static void sbp_targ_abort(struct sbp_targ_softc *, struct orb_info *); static void @@ -252,13 +272,19 @@ sbp_targ_dealloc_login(struct sbp_targ_l } for (orbi = STAILQ_FIRST(&login->orbs); orbi != NULL; orbi = next) { next = STAILQ_NEXT(orbi, link); + if (debug) + printf("%s: free orbi %p\n", __func__, orbi); free(orbi, M_SBP_TARG); + orbi = NULL; } callout_stop(&login->hold_callout); STAILQ_REMOVE(&login->lstate->logins, login, sbp_targ_login, link); login->lstate->sc->logins[login->id] = NULL; + if (debug) + printf("%s: free login %p\n", __func__, login); free((void *)login, M_SBP_TARG); + login = NULL; } static void @@ -361,20 +387,26 @@ sbp_targ_find_devs(struct sbp_targ_softc if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { *lstate = sc->black_hole; + if (debug) + printf("setting black hole for this target id(%d)\n", ccb->ccb_h.target_id); return (CAM_REQ_CMP); } - if (ccb->ccb_h.target_id != 0) - return (CAM_TID_INVALID); - lun = ccb->ccb_h.target_lun; if (lun >= MAX_LUN) return (CAM_LUN_INVALID); *lstate = sc->lstate[lun]; - if (notfound_failure != 0 && *lstate == NULL) + if (notfound_failure != 0 && *lstate == NULL) { + if (debug) + printf("%s: lstate for lun is invalid, target(%d), lun(%d)\n", + __func__, ccb->ccb_h.target_id, lun); return (CAM_PATH_INVALID); + } else + if (debug) + printf("%s: setting lstate for tgt(%d) lun(%d)\n", + __func__,ccb->ccb_h.target_id, lun); return (CAM_REQ_CMP); } @@ -411,11 +443,18 @@ sbp_targ_en_lun(struct sbp_targ_softc *s printf("Couldn't allocate lstate\n"); ccb->ccb_h.status = CAM_RESRC_UNAVAIL; return; - } - if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) + } else { + if (debug) + printf("%s: malloc'd lstate %p\n",__func__, lstate); + } + if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) { sc->black_hole = lstate; - else + if (debug) + printf("Blackhole set due to target id == %d\n", + ccb->ccb_h.target_id); + } else sc->lstate[ccb->ccb_h.target_lun] = lstate; + memset(lstate, 0, sizeof(*lstate)); lstate->sc = sc; status = xpt_create_path(&lstate->path, /*periph*/NULL, @@ -424,6 +463,7 @@ sbp_targ_en_lun(struct sbp_targ_softc *s xpt_path_lun_id(ccb->ccb_h.path)); if (status != CAM_REQ_CMP) { free(lstate, M_SBP_TARG); + lstate = NULL; xpt_print_path(ccb->ccb_h.path); printf("Couldn't allocate path\n"); ccb->ccb_h.status = CAM_RESRC_UNAVAIL; @@ -443,6 +483,7 @@ sbp_targ_en_lun(struct sbp_targ_softc *s if (lstate == NULL) { ccb->ccb_h.status = CAM_LUN_INVALID; + printf("Invalid lstate for this target\n"); return; } ccb->ccb_h.status = CAM_REQ_CMP; @@ -458,6 +499,7 @@ sbp_targ_en_lun(struct sbp_targ_softc *s } if (ccb->ccb_h.status != CAM_REQ_CMP) { + printf("status != CAM_REQ_CMP\n"); return; } @@ -475,7 +517,10 @@ sbp_targ_en_lun(struct sbp_targ_softc *s sc->black_hole = NULL; else sc->lstate[ccb->ccb_h.target_lun] = NULL; + if (debug) + printf("%s: free lstate %p\n", __func__, lstate); free(lstate, M_SBP_TARG); + lstate = NULL; /* bus reset */ sc->fd.fc->ibr(sc->fd.fc); @@ -538,7 +583,7 @@ sbp_targ_get_orb_info(struct sbp_targ_ls if (orbi->orb_lo == tag_id) goto found; printf("%s: orb not found tag_id=0x%08x init_id=%d\n", - __func__, tag_id, init_id); + __func__, tag_id, init_id); return (NULL); found: return (orbi); @@ -559,12 +604,13 @@ sbp_targ_abort(struct sbp_targ_softc *sc xpt_done(orbi->ccb); orbi->ccb = NULL; } -#if 0 if (orbi->state <= ORBI_STATUS_ATIO) { sbp_targ_remove_orb_info_locked(orbi->login, orbi); + if (debug) + printf("%s: free orbi %p\n", __func__, orbi); free(orbi, M_SBP_TARG); + orbi = NULL; } else -#endif orbi->state = ORBI_STATUS_ABORTED; } } @@ -576,12 +622,21 @@ sbp_targ_free_orbi(struct fw_xfer *xfer) { struct orb_info *orbi; - orbi = (struct orb_info *)xfer->sc; if (xfer->resp != 0) { /* XXX */ printf("%s: xfer->resp = %d\n", __func__, xfer->resp); } + orbi = (struct orb_info *)xfer->sc; + if ( orbi->page_table != NULL ) { + if (debug) + printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); + free(orbi->page_table, M_SBP_TARG); + orbi->page_table = NULL; + } + if (debug) + printf("%s: free orbi %p\n", __func__, orbi); free(orbi, M_SBP_TARG); + orbi = NULL; fw_xfer_free(xfer); } @@ -595,7 +650,7 @@ sbp_targ_status_FIFO(struct orb_info *or sbp_targ_remove_orb_info(orbi->login, orbi); xfer = fwmem_write_block(orbi->fwdev, (void *)orbi, - /*spd*/2, fifo_hi, fifo_lo, + /*spd*/FWSPD_S400, fifo_hi, fifo_lo, sizeof(uint32_t) * (orbi->status.len + 1), (char *)&orbi->status, sbp_targ_free_orbi); @@ -605,6 +660,10 @@ sbp_targ_status_FIFO(struct orb_info *or } } +/* + * Generate the appropriate CAM status for the + * target. + */ static void sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb) { @@ -621,6 +680,8 @@ sbp_targ_send_status(struct orb_info *or sbp_status->status = 0; /* XXX */ sbp_status->dead = 0; /* XXX */ + ccb->ccb_h.status= CAM_REQ_CMP; + switch (ccb->csio.scsi_status) { case SCSI_STATUS_OK: if (debug) @@ -628,8 +689,15 @@ sbp_targ_send_status(struct orb_info *or sbp_status->len = 1; break; case SCSI_STATUS_CHECK_COND: + if (debug) + printf("%s: STATUS SCSI_STATUS_CHECK_COND\n", __func__); + goto process_scsi_status; case SCSI_STATUS_BUSY: + if (debug) + printf("%s: STATUS SCSI_STATUS_BUSY\n", __func__); + goto process_scsi_status; case SCSI_STATUS_CMD_TERMINATED: +process_scsi_status: { struct sbp_cmd_status *sbp_cmd_status; struct scsi_sense_data *sense; @@ -640,9 +708,6 @@ sbp_targ_send_status(struct orb_info *or int64_t sinfo; int sense_len; - if (debug) - printf("%s: STATUS %d\n", __func__, - ccb->csio.scsi_status); sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0]; sbp_cmd_status->status = ccb->csio.scsi_status; sense = &ccb->csio.sense_data; @@ -734,6 +799,7 @@ sbp_targ_send_status(struct orb_info *or if (scsi_get_sks(sense, sense_len, sks) == 0) { bcopy(sks, &sbp_cmd_status->s_keydep[0], sizeof(sks)); sbp_status->len = 5; + ccb->ccb_h.status |= CAM_SENT_SENSE; } break; @@ -743,13 +809,20 @@ sbp_targ_send_status(struct orb_info *or sbp_status->status); } - if (orbi->page_table != NULL) - free(orbi->page_table, M_SBP_TARG); sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); } +/* + * Invoked as a callback handler from fwmem_read/write_block + * + * Process read/write of initiator address space + * completion and pass status onto the backend target. + * If this is a partial read/write for a CCB then + * we decrement the orbi's refcount to indicate + * the status of the read/write is complete + */ static void sbp_targ_cam_done(struct fw_xfer *xfer) { @@ -758,7 +831,7 @@ sbp_targ_cam_done(struct fw_xfer *xfer) orbi = (struct orb_info *)xfer->sc; - if (debug > 1) + if (debug) printf("%s: resp=%d refcount=%d\n", __func__, xfer->resp, orbi->refcount); @@ -779,13 +852,26 @@ sbp_targ_cam_done(struct fw_xfer *xfer) if (debug) printf("%s: orbi aborted\n", __func__); sbp_targ_remove_orb_info(orbi->login, orbi); - if (orbi->page_table != NULL) + if (orbi->page_table != NULL) { + if (debug) + printf("%s: free orbi->page_table %p\n", + __func__, orbi->page_table); free(orbi->page_table, M_SBP_TARG); + } + if (debug) + printf("%s: free orbi %p\n", __func__, orbi); free(orbi, M_SBP_TARG); - } else if (orbi->status.resp == 0) { - if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) + orbi = NULL; + } else if (orbi->status.resp == ORBI_STATUS_NONE) { + if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { + if (debug) + printf("%s: CAM_SEND_STATUS set %0x\n", __func__, ccb->ccb_h.flags); sbp_targ_send_status(orbi, ccb); - ccb->ccb_h.status = CAM_REQ_CMP; + } else { + if (debug) + printf("%s: CAM_SEND_STATUS not set %0x\n", __func__, ccb->ccb_h.flags); + ccb->ccb_h.status = CAM_REQ_CMP; + } SBP_LOCK(orbi->sc); xpt_done(ccb); SBP_UNLOCK(orbi->sc); @@ -855,6 +941,13 @@ sbp_targ_abort_ccb(struct sbp_targ_softc return (CAM_PATH_INVALID); } +/* + * directly execute a read or write to the initiator + * address space and set hand(sbp_targ_cam_done) to + * process the completion from the SIM to the target. + * set orbi->refcount to inidicate that a read/write + * is inflight to/from the initiator. + */ static void sbp_targ_xfer_buf(struct orb_info *orbi, u_int offset, uint16_t dst_hi, uint32_t dst_lo, u_int size, @@ -874,16 +967,21 @@ sbp_targ_xfer_buf(struct orb_info *orbi, len = MIN(size, 2048 /* XXX */); size -= len; orbi->refcount ++; - if (ccb_dir == CAM_DIR_OUT) + if (ccb_dir == CAM_DIR_OUT) { + if (debug) + printf("%s: CAM_DIR_OUT --> read block in?\n",__func__); xfer = fwmem_read_block(orbi->fwdev, - (void *)orbi, /*spd*/2, + (void *)orbi, /*spd*/FWSPD_S400, dst_hi, dst_lo + off, len, ptr + off, hand); - else + } else { + if (debug) + printf("%s: CAM_DIR_IN --> write block out?\n",__func__); xfer = fwmem_write_block(orbi->fwdev, - (void *)orbi, /*spd*/2, + (void *)orbi, /*spd*/FWSPD_S400, dst_hi, dst_lo + off, len, ptr + off, hand); + } if (xfer == NULL) { printf("%s: xfer == NULL", __func__); /* XXX what should we do?? */ @@ -897,18 +995,22 @@ static void sbp_targ_pt_done(struct fw_xfer *xfer) { struct orb_info *orbi; - union ccb *ccb; - u_int i, offset, res, len; - uint32_t t1, t2, *p; + struct unrestricted_page_table_fmt *pt; + uint32_t i; orbi = (struct orb_info *)xfer->sc; - ccb = orbi->ccb; + if (orbi->state == ORBI_STATUS_ABORTED) { if (debug) printf("%s: orbi aborted\n", __func__); sbp_targ_remove_orb_info(orbi->login, orbi); + if (debug) { + printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); + printf("%s: free orbi %p\n", __func__, orbi); + } free(orbi->page_table, M_SBP_TARG); free(orbi, M_SBP_TARG); + orbi = NULL; fw_xfer_free(xfer); return; } @@ -920,60 +1022,158 @@ sbp_targ_pt_done(struct fw_xfer *xfer) orbi->status.len = 1; sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); + if (debug) + printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); + sbp_targ_status_FIFO(orbi, orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); free(orbi->page_table, M_SBP_TARG); + orbi->page_table = NULL; fw_xfer_free(xfer); return; } - res = ccb->csio.dxfer_len; - offset = 0; - if (debug) - printf("%s: dxfer_len=%d\n", __func__, res); - orbi->refcount ++; - for (p = orbi->page_table, i = orbi->orb4.data_size; i > 0; i --) { - t1 = ntohl(*p++); - t2 = ntohl(*p++); - if (debug > 1) - printf("page_table: %04x:%08x %d\n", - t1 & 0xffff, t2, t1>>16); - len = MIN(t1 >> 16, res); - res -= len; - sbp_targ_xfer_buf(orbi, offset, t1 & 0xffff, t2, len, - sbp_targ_cam_done); - offset += len; - if (res == 0) - break; + orbi->refcount++; +/* + * Set endianess here so we don't have + * to deal with is later + */ + for (i = 0, pt = orbi->page_table; i < orbi->orb4.data_size; i++, pt++) { + pt->segment_len = ntohs(pt->segment_len); + if (debug) + printf("%s:segment_len = %u\n", __func__,pt->segment_len); + pt->segment_base_high = ntohs(pt->segment_base_high); + pt->segment_base_low = ntohl(pt->segment_base_low); } - orbi->refcount --; + + sbp_targ_xfer_pt(orbi); + + orbi->refcount--; if (orbi->refcount == 0) printf("%s: refcount == 0\n", __func__); - if (res !=0) - /* XXX handle res != 0 case */ - printf("%s: page table is too small(%d)\n", __func__, res); fw_xfer_free(xfer); return; } +static void sbp_targ_xfer_pt(struct orb_info *orbi) +{ + union ccb *ccb; + uint32_t res, offset, len; + + ccb = orbi->ccb; + if (debug) + printf("%s: dxfer_len=%d\n", __func__, ccb->csio.dxfer_len); + res = ccb->csio.dxfer_len; + /* + * If the page table required multiple CTIO's to + * complete, then cur_pte is non NULL + * and we need to start from the last position + * If this is the first pass over a page table + * then we just start at the beginning of the page + * table. + * + * Parse the unrestricted page table and figure out where we need + * to shove the data from this read request. + */ + for (offset = 0, len = 0; (res != 0) && (orbi->cur_pte < orbi->last_pte); offset += len) { + len = MIN(orbi->cur_pte->segment_len, res); + res -= len; + if (debug) + printf("%s:page_table: %04x:%08x segment_len(%u) res(%u) len(%u)\n", + __func__, orbi->cur_pte->segment_base_high, + orbi->cur_pte->segment_base_low, + orbi->cur_pte->segment_len, + res, len); + sbp_targ_xfer_buf(orbi, offset, + orbi->cur_pte->segment_base_high, + orbi->cur_pte->segment_base_low, + len, sbp_targ_cam_done); + /* + * If we have only written partially to + * this page table, then we need to save + * our position for the next CTIO. If we + * have completed the page table, then we + * are safe to move on to the next entry. + */ + if (len == orbi->cur_pte->segment_len) { + orbi->cur_pte++; + } else { + uint32_t saved_base_low; + + /* Handle transfers that cross a 4GB boundary. */ + saved_base_low = orbi->cur_pte->segment_base_low; + orbi->cur_pte->segment_base_low += len; + if (orbi->cur_pte->segment_base_low < saved_base_low) + orbi->cur_pte->segment_base_high++; + + orbi->cur_pte->segment_len -= len; + } + } + if (debug) { + printf("%s: base_low(%08x) page_table_off(%p) last_block(%u)\n", + __func__, orbi->cur_pte->segment_base_low, + orbi->cur_pte, orbi->last_block_read); + } + if (res != 0) + printf("Warning - short pt encountered. " + "Could not transfer all data.\n"); + return; +} + +/* + * Create page table in local memory + * and transfer it from the initiator + * in order to know where we are supposed + * to put the data. + */ + static void sbp_targ_fetch_pt(struct orb_info *orbi) { struct fw_xfer *xfer; - if (debug) - printf("%s: page_table_size=%d\n", - __func__, orbi->orb4.data_size); - orbi->page_table = malloc(orbi->orb4.data_size*8, M_SBP_TARG, M_NOWAIT); - if (orbi->page_table == NULL) - goto error; - xfer = fwmem_read_block(orbi->fwdev, (void *)orbi, /*spd*/2, - orbi->data_hi, orbi->data_lo, orbi->orb4.data_size*8, - (void *)orbi->page_table, sbp_targ_pt_done); - if (xfer != NULL) + /* + * Pull in page table from initiator + * and setup for data from our + * backend device. + */ + if (orbi->page_table == NULL) { + orbi->page_table = malloc(orbi->orb4.data_size* + sizeof(struct unrestricted_page_table_fmt), + M_SBP_TARG, M_NOWAIT|M_ZERO); + if (orbi->page_table == NULL) + goto error; + orbi->cur_pte = orbi->page_table; + orbi->last_pte = orbi->page_table + orbi->orb4.data_size; + orbi->last_block_read = orbi->orb4.data_size; + if (debug && orbi->page_table != NULL) + printf("%s: malloc'd orbi->page_table(%p), orb4.data_size(%u)\n", + __func__, orbi->page_table, orbi->orb4.data_size); + + xfer = fwmem_read_block(orbi->fwdev, (void *)orbi, /*spd*/FWSPD_S400, + orbi->data_hi, orbi->data_lo, orbi->orb4.data_size* + sizeof(struct unrestricted_page_table_fmt), + (void *)orbi->page_table, sbp_targ_pt_done); + + if (xfer != NULL) + return; + } else { + /* + * This is a CTIO for a page table we have + * already malloc'd, so just directly invoke + * the xfer function on the orbi. + */ + sbp_targ_xfer_pt(orbi); return; + } error: orbi->ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + if (debug) + printf("%s: free orbi->page_table %p due to xfer == NULL\n", __func__, orbi->page_table); + if (orbi->page_table != NULL) { + free(orbi->page_table, M_SBP_TARG); + orbi->page_table = NULL; + } xpt_done(orbi->ccb); return; } @@ -1016,6 +1216,8 @@ sbp_targ_action1(struct cam_sim *sim, un if (debug) printf("%s: ctio aborted\n", __func__); sbp_targ_remove_orb_info_locked(orbi->login, orbi); + if (debug) + printf("%s: free orbi %p\n", __func__, orbi); free(orbi, M_SBP_TARG); ccb->ccb_h.status = CAM_REQ_ABORTED; xpt_done(ccb); @@ -1051,17 +1253,16 @@ sbp_targ_action1(struct cam_sim *sim, un } /* Sanity check */ - if (ccb_dir != CAM_DIR_NONE && - orbi->orb4.data_size != ccb->csio.dxfer_len) - printf("%s: data_size(%d) != dxfer_len(%d)\n", - __func__, orbi->orb4.data_size, - ccb->csio.dxfer_len); - - if (ccb_dir != CAM_DIR_NONE) + if (ccb_dir != CAM_DIR_NONE) { sbp_targ_xfer_buf(orbi, 0, orbi->data_hi, orbi->data_lo, MIN(orbi->orb4.data_size, ccb->csio.dxfer_len), sbp_targ_cam_done); + if ( orbi->orb4.data_size > ccb->csio.dxfer_len ) { + orbi->data_lo += ccb->csio.dxfer_len; + orbi->orb4.data_size -= ccb->csio.dxfer_len; + } + } if (ccb_dir == CAM_DIR_NONE) { if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { @@ -1125,7 +1326,8 @@ sbp_targ_action1(struct cam_sim *sim, un cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; - cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE; + cpi->transport = XPORT_SPI; /* FIXME add XPORT_FW type to cam */ + cpi->hba_misc = PIM_NOBUSRESET | PIM_NOBUSRESET; cpi->hba_eng_cnt = 0; cpi->max_target = 7; /* XXX */ cpi->max_lun = MAX_LUN - 1; @@ -1163,10 +1365,42 @@ sbp_targ_action1(struct cam_sim *sim, un xpt_done(ccb); break; } +#ifdef CAM_NEW_TRAN_CODE + case XPT_SET_TRAN_SETTINGS: + ccb->ccb_h.status = CAM_REQ_INVALID; + xpt_done(ccb); + break; + case XPT_GET_TRAN_SETTINGS: + { + struct ccb_trans_settings *cts = &ccb->cts; + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_FW; /* should have a FireWire */ + cts->transport_version = 2; + spi->valid = CTS_SPI_VALID_DISC; + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + scsi->valid = CTS_SCSI_VALID_TQ; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; +#if 0 + printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:\n", + device_get_nameunit(sc->fd.dev), + ccb->ccb_h.target_id, ccb->ccb_h.target_lun); +#endif + cts->ccb_h.status = CAM_REQ_CMP; + xpt_done(ccb); + break; + } +#endif + default: - printf("%s: unknown function %d\n", + printf("%s: unknown function 0x%x\n", __func__, ccb->ccb_h.func_code); - ccb->ccb_h.status = CAM_REQ_INVALID; + ccb->ccb_h.status = CAM_PROVIDE_FAIL; xpt_done(ccb); break; } @@ -1245,7 +1479,7 @@ sbp_targ_cmd_handler(struct fw_xfer *xfe atio->ccb_h.target_id = 0; /* XXX */ atio->ccb_h.target_lun = orbi->login->lstate->lun; atio->sense_len = 0; - atio->tag_action = 1; /* XXX */ + atio->tag_action = MSG_SIMPLE_TASK; atio->tag_id = orbi->orb_lo; atio->init_id = orbi->login->id; @@ -1429,7 +1663,7 @@ sbp_targ_mgm_handler(struct fw_xfer *xfe login->loginres.recon_hold = htons(login->hold_sec); STAILQ_INSERT_TAIL(&lstate->logins, login, link); - fwmem_write_block(orbi->fwdev, NULL, /*spd*/2, orb[2], orb[3], + fwmem_write_block(orbi->fwdev, NULL, /*spd*/FWSPD_S400, orb[2], orb[3], sizeof(struct sbp_login_res), (void *)&login->loginres, fw_asy_callback_free); /* XXX return status after loginres is successfully written */ @@ -1515,10 +1749,11 @@ sbp_targ_fetch_orb(struct sbp_targ_softc orbi->orb_lo = orb_lo; orbi->status.orb_hi = htons(orb_hi); orbi->status.orb_lo = htonl(orb_lo); + orbi->page_table = NULL; switch (mode) { case FETCH_MGM: - fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, + fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, sizeof(uint32_t) * 8, &orbi->orb[0], sbp_targ_mgm_handler); break; @@ -1545,14 +1780,14 @@ sbp_targ_fetch_orb(struct sbp_targ_softc SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); STAILQ_INSERT_TAIL(&login->orbs, orbi, link); SBP_UNLOCK(sc); - fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, + fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, sizeof(uint32_t) * 8, &orbi->orb[0], sbp_targ_cmd_handler); break; case FETCH_POINTER: orbi->state = ORBI_STATUS_POINTER; login->flags |= F_LINK_ACTIVE; - fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, + fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, sizeof(uint32_t) * 2, &orbi->orb[0], sbp_targ_pointer_handler); break; @@ -1709,7 +1944,7 @@ done: if (rtcode != 0) printf("%s: rtcode = %d\n", __func__, rtcode); sfp = &xfer->send.hdr; - xfer->send.spd = 2; /* XXX */ + xfer->send.spd = FWSPD_S400; xfer->hand = sbp_targ_resp_callback; sfp->mode.wres.dst = fp->mode.wreqb.src; sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201252333.q0PNXoWK050308>