Mercurial > illumos > illumos-gate
changeset 276:7c784ab26b5a
6239895 scsa1394: panic seen when doing a cp -r to a mounted hard drive
6260568 scsa1394 panics kernel when attempting to access firewire disk
6262353 scsa1394: assertion failed: num_cmds != 0, file: ../../common/io/1394/t1394.c
6271950 scsa1394 support for vold hotplug
6272461 Null pointer panic in sbp2_ses_remove_task_locked()
6273456 panic seen when restarting vold on an SB2500 with a firewire disk
author | artem |
---|---|
date | Tue, 02 Aug 2005 16:40:23 -0700 |
parents | b765b3d4d672 |
children | 1e4ddc05e491 |
files | usr/src/uts/common/io/1394/targets/scsa1394/hba.c usr/src/uts/common/io/1394/targets/scsa1394/sbp2_driver.c usr/src/uts/common/io/sbp2/sbp2.c usr/src/uts/common/sys/1394/targets/scsa1394/impl.h |
diffstat | 4 files changed, 86 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/1394/targets/scsa1394/hba.c Tue Aug 02 14:37:02 2005 -0700 +++ b/usr/src/uts/common/io/1394/targets/scsa1394/hba.c Tue Aug 02 16:40:23 2005 -0700 @@ -873,12 +873,15 @@ return (DDI_FAILURE); } - ret = scsa1394_sbp2_login(sp, lun); - - return (ret); + if (scsa1394_dev_is_online(sp)) { + return (scsa1394_sbp2_login(sp, lun)); + } else { + return (DDI_FAILURE); + } } - if ((lun >= sp->s_nluns) || (sp->s_lun[lun].l_cdip != NULL)) { + if ((lun >= sp->s_nluns) || (sp->s_lun[lun].l_cdip != NULL) || + !scsa1394_dev_is_online(sp)) { return (DDI_FAILURE); } @@ -1447,6 +1450,7 @@ ddi_dma_free_handle(&cmd->sc_buf_dma_hdl); return (DDI_FAILURE); } + lp->l_stat.stat_cmd_buf_dma_partial++; break; case DDI_DMA_NORESOURCES: @@ -1546,8 +1550,12 @@ nsegs = max(ccount, cmd->sc_win_len / SBP2_PT_SEGSIZE_MAX) * 2; segsize_max = SBP2_PT_SEGSIZE_MAX; } else { - /* For Symbios workaround we know exactly the number of pages */ - nsegs = howmany(cmd->sc_win_len, scsa1394_symbios_page_size); + /* + * For Symbios workaround we know exactly the number of segments + * Additional segment may be needed if buffer is not aligned. + */ + nsegs = + howmany(cmd->sc_win_len, scsa1394_symbios_page_size) + 1; segsize_max = scsa1394_symbios_page_size; } @@ -1777,7 +1785,9 @@ /* * setup page table if needed */ - if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX)) { + if ((ccount == 1) && (dmac.dmac_size <= SBP2_PT_SEGSIZE_MAX) && + (!sp->s_symbios || + (dmac.dmac_size <= scsa1394_symbios_page_size))) { /* but first, free old resources */ if (cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID) { scsa1394_cmd_pt_dma_free(sp, cmd); @@ -1823,19 +1833,6 @@ scsa1394_lun_t *lp = cmd->sc_lun; int ret; - mutex_enter(&sp->s_mutex); - if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { - if (sp->s_dev_state == SCSA1394_DEV_BUS_RESET) { - /* this should prevent scary console messages */ - mutex_exit(&sp->s_mutex); - return (TRAN_BUSY); - } else { - mutex_exit(&sp->s_mutex); - return (TRAN_FATAL_ERROR); - } - } - mutex_exit(&sp->s_mutex); - /* * since we don't support polled I/O, just accept the packet * so the rest of the file systems get synced properly @@ -1850,6 +1847,20 @@ return (TRAN_BADPKT); } + mutex_enter(&sp->s_mutex); + if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { + /* + * If device is temporarily gone due to bus reset, + * return busy to prevent prevent scary console messages. + * If permanently gone, leave it to scsa1394_cmd_fake_comp(). + */ + if (sp->s_dev_state == SCSA1394_DEV_BUS_RESET) { + mutex_exit(&sp->s_mutex); + return (TRAN_BUSY); + } + } + mutex_exit(&sp->s_mutex); + if ((ap->a_lun >= sp->s_nluns) || (ap->a_lun != pkt->pkt_address.a_lun)) { return (TRAN_BADPKT); @@ -1967,9 +1978,12 @@ case SCMD_WRITE_LONG: lba = SCSA1394_LBA_10BYTE(pkt); len = SCSA1394_LEN_10BYTE(pkt); - sz = SCSA1394_CDRW_BLKSZ(bp->b_bcount, len); - if (SCSA1394_VALID_CDRW_BLKSZ(sz)) { - blk_size = sz; + if ((lp->l_dtype_orig == DTYPE_RODIRECT) && + (bp != NULL) && (len != 0)) { + sz = SCSA1394_CDRW_BLKSZ(bp->b_bcount, len); + if (SCSA1394_VALID_CDRW_BLKSZ(sz)) { + blk_size = sz; + } } break; case SCMD_READ_CD: @@ -1990,12 +2004,12 @@ scsa1394_cmd_fill_cdb_other(lp, cmd); return; } + cmd->sc_blk_size = blk_size; /* limit xfer length for Symbios workaround */ if (sp->s_symbios && (len * blk_size > scsa1394_symbios_size_max)) { cmd->sc_flags |= SCSA1394_CMD_SYMBIOS_BREAKUP; - cmd->sc_blk_size = blk_size; cmd->sc_total_blks = cmd->sc_resid_blks = len; len = scsa1394_symbios_size_max / blk_size; @@ -2026,9 +2040,12 @@ { struct scsi_pkt *pkt = CMD2PKT(cmd); - bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len); + cmd->sc_xfer_bytes = cmd->sc_win_len; + cmd->sc_xfer_blks = cmd->sc_xfer_bytes / lp->l_lba_size; + cmd->sc_total_blks = cmd->sc_xfer_blks; + cmd->sc_lba = 0; - cmd->sc_xfer_bytes = cmd->sc_win_len; + bcopy(pkt->pkt_cdbp, cmd->sc_cdb, cmd->sc_cdb_len); } /* @@ -2163,6 +2180,21 @@ scsa1394_lun_t *lp = cmd->sc_lun; int ret = DDI_SUCCESS; + /* + * agreement with sd in case of device hot removal + * is to fake completion with CMD_DEV_GONE + */ + mutex_enter(&sp->s_mutex); + if (sp->s_dev_state != SCSA1394_DEV_ONLINE) { + mutex_exit(&sp->s_mutex); + pkt->pkt_reason = CMD_DEV_GONE; + if (pkt->pkt_comp) { + (*pkt->pkt_comp)(pkt); + } + return (DDI_SUCCESS); + } + mutex_exit(&sp->s_mutex); + mutex_enter(&lp->l_mutex); switch (pkt->pkt_cdbp[0]) {
--- a/usr/src/uts/common/io/1394/targets/scsa1394/sbp2_driver.c Tue Aug 02 14:37:02 2005 -0700 +++ b/usr/src/uts/common/io/1394/targets/scsa1394/sbp2_driver.c Tue Aug 02 16:40:23 2005 -0700 @@ -497,36 +497,44 @@ static void scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd) { - size_t offset; - int start_page; sbp2_pt_unrestricted_t *pt; scsa1394_cmd_seg_t *seg; - size_t resid; int nsegs; + size_t resid, skiplen, dataoff, segoff, seglen; + uint64_t baddr; - /* calculate page table address and size */ + /* data offset within command */ if (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP) { - offset = (cmd->sc_total_blks - cmd->sc_resid_blks) * + dataoff = (cmd->sc_total_blks - cmd->sc_resid_blks) * cmd->sc_blk_size; } else { - offset = 0; + dataoff = 0; } - start_page = offset / scsa1394_symbios_page_size; + + /* skip dataoff bytes */ + seg = &cmd->sc_buf_seg[0]; + skiplen = 0; + while (skiplen + seg->ss_len <= dataoff) { + skiplen += seg->ss_len; + seg++; + } + segoff = dataoff - skiplen; /* offset within segment */ pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr; - seg = &cmd->sc_buf_seg[start_page]; resid = cmd->sc_xfer_bytes; nsegs = 0; while (resid > 0) { ASSERT(seg->ss_len <= scsa1394_symbios_page_size); - pt->pt_seg_len = min(seg->ss_len, resid); - resid -= pt->pt_seg_len; - SBP2_SWAP16_1(pt->pt_seg_len); + seglen = min(seg->ss_len, resid) - segoff; + baddr = seg->ss_baddr + segoff; - pt->pt_seg_base_hi = SBP2_SWAP16(seg->ss_baddr >> 32); - pt->pt_seg_base_lo = SBP2_SWAP32(seg->ss_baddr & 0xFFFFFFFF); + pt->pt_seg_len = SBP2_SWAP16(seglen); + pt->pt_seg_base_hi = SBP2_SWAP16(baddr >> 32); + pt->pt_seg_base_lo = SBP2_SWAP32(baddr & 0xFFFFFFFF); + segoff = 0; + resid -= seglen; nsegs++; pt++; seg++;
--- a/usr/src/uts/common/io/sbp2/sbp2.c Tue Aug 02 14:37:02 2005 -0700 +++ b/usr/src/uts/common/io/sbp2/sbp2.c Tue Aug 02 16:40:23 2005 -0700 @@ -389,9 +389,11 @@ } if (tp->t_mgt_cmd) { SBP2_FREE_CMD(tp, tp->t_mgt_cmd); + tp->t_mgt_cmd = NULL; } if (tp->t_mgt_cmd_data) { freeb(tp->t_mgt_cmd_data); + tp->t_mgt_cmd_data = NULL; } } @@ -951,7 +953,7 @@ * otherwise use callback. */ callback = (ap->a_active_task != new_task); - task = ap->a_active_task; + ASSERT(task == ap->a_active_task); ap->a_active_task = NULL; mutex_exit(&ap->a_mutex); sbp2_agent_release(ap); @@ -961,12 +963,12 @@ * to SBP2_TASK_COMP while it's still on the list, to avoid race with * upper layer driver (e.g. scsa1394). */ - ret = sbp2_ses_remove_task(sp, new_task); + ret = sbp2_ses_remove_task(sp, task); ASSERT(ret == SBP2_SUCCESS); - new_task->ts_state = SBP2_TASK_COMP; + task->ts_state = SBP2_TASK_COMP; if (callback) { - sp->s_status_cb(sp->s_status_cb_arg, new_task); + sp->s_status_cb(sp->s_status_cb_arg, task); return (SBP2_SUCCESS); } else { /* upper layer driver is responsible to call nudge */
--- a/usr/src/uts/common/sys/1394/targets/scsa1394/impl.h Tue Aug 02 14:37:02 2005 -0700 +++ b/usr/src/uts/common/sys/1394/targets/scsa1394/impl.h Tue Aug 02 16:40:23 2005 -0700 @@ -95,6 +95,7 @@ uint_t stat_cmd_cnt; /* # of commands submitted */ uint_t stat_cmd_buf_max_nsegs; + uint_t stat_cmd_buf_dma_partial; /* * errors