[SCSI] mvsas: misc improvements
authorXiangliang Yu <yuxiangl@marvell.com>
Tue, 24 May 2011 14:37:25 +0000 (22:37 +0800)
committerJames Bottomley <JBottomley@Parallels.com>
Tue, 26 Jul 2011 06:38:01 +0000 (10:38 +0400)
Change code to match HBA datasheet.
Change code to make it readable.
Add support big endian for mvs_prd_imt.
Add cpu_to_le32 and cpu_to_le64 to use on addr.
Add scan_finished for structure mvs_prv_info.

Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/mvsas/mv_64xx.c
drivers/scsi/mvsas/mv_94xx.c
drivers/scsi/mvsas/mv_94xx.h
drivers/scsi/mvsas/mv_chips.h
drivers/scsi/mvsas/mv_init.c
drivers/scsi/mvsas/mv_sas.c
drivers/scsi/mvsas/mv_sas.h

index 702c767ee46f04f5e19e18873fe56ae29f439464..bc75ba7488d860dffec6d3c9e63e01342783dc65 100644 (file)
@@ -58,24 +58,17 @@ static void __devinit mvs_64xx_enable_xmt(struct mvs_info *mvi, int phy_id)
 static void __devinit mvs_64xx_phy_hacks(struct mvs_info *mvi)
 {
        void __iomem *regs = mvi->regs;
+       int i;
 
        mvs_phy_hacks(mvi);
 
        if (!(mvi->flags & MVF_FLAG_SOC)) {
                /* TEST - for phy decoding error, adjust voltage levels */
-               mw32(MVS_P0_VSR_ADDR + 0, 0x8);
-               mw32(MVS_P0_VSR_DATA + 0, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 8, 0x8);
-               mw32(MVS_P0_VSR_DATA + 8, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 16, 0x8);
-               mw32(MVS_P0_VSR_DATA + 16, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 24, 0x8);
-               mw32(MVS_P0_VSR_DATA + 24, 0x2F0);
+               for (i = 0; i < MVS_SOC_PORTS; i++) {
+                       mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE8);
+                       mvs_write_port_vsr_data(mvi, i, 0x2F0);
+               }
        } else {
-               int i;
                /* disable auto port detection */
                mw32(MVS_GBL_PORT_TYPE, 0);
                for (i = 0; i < mvi->chip->n_phy; i++) {
@@ -321,6 +314,11 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
        /* init phys */
        mvs_64xx_phy_hacks(mvi);
 
+       tmp = mvs_cr32(mvi, CMD_PHY_MODE_21);
+       tmp &= 0x0000ffff;
+       tmp |= 0x00fa0000;
+       mvs_cw32(mvi, CMD_PHY_MODE_21, tmp);
+
        /* enable auto port detection */
        mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN);
 
@@ -394,13 +392,17 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
        /* reset CMD queue */
        tmp = mr32(MVS_PCS);
        tmp |= PCS_CMD_RST;
+       tmp &= ~PCS_SELF_CLEAR;
        mw32(MVS_PCS, tmp);
        /* interrupt coalescing may cause missing HW interrput in some case,
         * and the max count is 0x1ff, while our max slot is 0x200,
         * it will make count 0.
         */
        tmp = 0;
-       mw32(MVS_INT_COAL, tmp);
+       if (MVS_CHIP_SLOT_SZ > 0x1ff)
+               mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
+       else
+               mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);
 
        tmp = 0x10000 | interrupt_coalescing;
        mw32(MVS_INT_COAL_TMOUT, tmp);
index a0ec4aaa24a2f233264fcda751bc748be659a997..1276e494b868bb0d6202e0aa3490c98c6a495270 100644 (file)
@@ -271,7 +271,14 @@ static void __devinit mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id)
 static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
 {
        u32 tmp;
-
+       u32 delay = 5000;
+       if (hard == MVS_PHY_TUNE) {
+               mvs_write_port_cfg_addr(mvi, phy_id, PHYR_SATA_CTL);
+               tmp = mvs_read_port_cfg_data(mvi, phy_id);
+               mvs_write_port_cfg_data(mvi, phy_id, tmp|0x20000000);
+               mvs_write_port_cfg_data(mvi, phy_id, tmp|0x100000);
+               return;
+       }
        tmp = mvs_read_port_irq_stat(mvi, phy_id);
        tmp &= ~PHYEV_RDY_CH;
        mvs_write_port_irq_stat(mvi, phy_id, tmp);
@@ -281,12 +288,15 @@ static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
                mvs_write_phy_ctl(mvi, phy_id, tmp);
                do {
                        tmp = mvs_read_phy_ctl(mvi, phy_id);
-               } while (tmp & PHY_RST_HARD);
+                       udelay(10);
+                       delay--;
+               } while ((tmp & PHY_RST_HARD) && delay);
+               if (!delay)
+                       mv_dprintk("phy hard reset failed.\n");
        } else {
-               mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_STAT);
-               tmp = mvs_read_port_vsr_data(mvi, phy_id);
+               tmp = mvs_read_phy_ctl(mvi, phy_id);
                tmp |= PHY_RST;
-               mvs_write_port_vsr_data(mvi, phy_id, tmp);
+               mvs_write_phy_ctl(mvi, phy_id, tmp);
        }
 }
 
@@ -413,7 +423,7 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
                mvs_94xx_phy_disable(mvi, i);
                /* set phy local SAS address */
                mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4,
-                                               (mvi->phy[i].dev_sas_addr));
+                                               cpu_to_le64(mvi->phy[i].dev_sas_addr));
 
                mvs_94xx_enable_xmt(mvi, i);
                mvs_94xx_config_reg_from_hba(mvi, i);
@@ -459,7 +469,6 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
         */
        cctl = mr32(MVS_CTL);
        cctl |= CCTL_ENDIAN_CMD;
-       cctl |= CCTL_ENDIAN_DATA;
        cctl &= ~CCTL_ENDIAN_OPEN;
        cctl |= CCTL_ENDIAN_RSP;
        mw32_f(MVS_CTL, cctl);
@@ -467,13 +476,17 @@ static int __devinit mvs_94xx_init(struct mvs_info *mvi)
        /* reset CMD queue */
        tmp = mr32(MVS_PCS);
        tmp |= PCS_CMD_RST;
+       tmp &= ~PCS_SELF_CLEAR;
        mw32(MVS_PCS, tmp);
        /* interrupt coalescing may cause missing HW interrput in some case,
         * and the max count is 0x1ff, while our max slot is 0x200,
         * it will make count 0.
         */
        tmp = 0;
-       mw32(MVS_INT_COAL, tmp);
+       if (MVS_CHIP_SLOT_SZ > 0x1ff)
+               mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
+       else
+               mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);
 
        tmp = 0x10000 | interrupt_coalescing;
        mw32(MVS_INT_COAL_TMOUT, tmp);
@@ -674,24 +687,16 @@ static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
 static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
 {
        void __iomem *regs = mvi->regs;
-       u32 tmp;
        u8 reg_set = *tfs;
 
        if (*tfs == MVS_ID_NOT_MAPPED)
                return;
 
        mvi->sata_reg_set &= ~bit(reg_set);
-       if (reg_set < 32) {
+       if (reg_set < 32)
                w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set);
-               tmp = mr32(MVS_INT_STAT_SRS_0) & (u32)mvi->sata_reg_set;
-               if (tmp)
-                       mw32(MVS_INT_STAT_SRS_0, tmp);
-       } else {
-               w_reg_set_enable(reg_set, mvi->sata_reg_set);
-               tmp = mr32(MVS_INT_STAT_SRS_1) & mvi->sata_reg_set;
-               if (tmp)
-                       mw32(MVS_INT_STAT_SRS_1, tmp);
-       }
+       else
+               w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32));
 
        *tfs = MVS_ID_NOT_MAPPED;
 
@@ -707,7 +712,7 @@ static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)
                return 0;
 
        i = mv_ffc64(mvi->sata_reg_set);
-       if (i > 32) {
+       if (i >= 32) {
                mvi->sata_reg_set |= bit(i);
                w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32));
                *tfs = i;
@@ -726,9 +731,12 @@ static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd)
        int i;
        struct scatterlist *sg;
        struct mvs_prd *buf_prd = prd;
+       struct mvs_prd_imt im_len;
+       *(u32 *)&im_len = 0;
        for_each_sg(scatter, sg, nr, i) {
                buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
-               buf_prd->im_len.len = cpu_to_le32(sg_dma_len(sg));
+               im_len.len = sg_dma_len(sg);
+               buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
                buf_prd++;
        }
 }
@@ -751,7 +759,7 @@ static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id,
        for (i = 0; i < 7; i++) {
                mvs_write_port_cfg_addr(mvi, port_id,
                                        CONFIG_ID_FRAME0 + i * 4);
-               id_frame[i] = mvs_read_port_cfg_data(mvi, port_id);
+               id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
        }
        memcpy(id, id_frame, 28);
 }
@@ -766,7 +774,7 @@ static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id,
        for (i = 0; i < 7; i++) {
                mvs_write_port_cfg_addr(mvi, port_id,
                                        CONFIG_ATT_ID_FRAME0 + i * 4);
-               id_frame[i] = mvs_read_port_cfg_data(mvi, port_id);
+               id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
                mv_dprintk("94xx phy %d atta frame %d %x.\n",
                        port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]);
        }
@@ -924,8 +932,12 @@ void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,
        int i;
        struct mvs_prd *buf_prd = prd;
        dma_addr_t buf_dma;
+       struct mvs_prd_imt im_len;
+
+       *(u32 *)&im_len = 0;
        buf_prd += from;
 
+#define PRD_CHAINED_ENTRY 0x01
        if ((mvi->pdev->revision == VANIR_A0_REV) ||
                        (mvi->pdev->revision == VANIR_B0_REV))
                buf_dma = (phy_mask <= 0x08) ?
@@ -933,10 +945,16 @@ void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,
        else
                return;
 
-       for (i = 0; i < MAX_SG_ENTRY - from; i++) {
-               buf_prd->addr = cpu_to_le64(buf_dma);
-               buf_prd->im_len.len = cpu_to_le32(buf_len);
-               ++buf_prd;
+       for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) {
+               if (i == MAX_SG_ENTRY - 1) {
+                       buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1));
+                       im_len.len = 2;
+                       im_len.misc_ctl = PRD_CHAINED_ENTRY;
+               } else {
+                       buf_prd->addr = cpu_to_le64(buf_dma);
+                       im_len.len = buf_len;
+               }
+               buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
        }
 }
 
index 6fc2c105c9d7513e524404185da1795d803523e1..d8c12e057ae84a240ef045cfcda125c626e28277 100644 (file)
@@ -142,8 +142,8 @@ enum sas_sata_vsp_regs {
 
 enum chip_register_bits {
        PHY_MIN_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8),
-       PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 8),
-       PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (12),
+       PHY_MAX_SPP_PHYS_LINK_RATE_MASK = (0x7 << 12),
+       PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET = (16),
        PHY_NEG_SPP_PHYS_LINK_RATE_MASK =
                        (0x3 << PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET),
 };
@@ -219,17 +219,24 @@ union reg_phy_cfg {
 #define MAX_SG_ENTRY           255
 
 struct mvs_prd_imt {
+#ifndef __BIG_ENDIAN
        __le32                  len:22;
        u8                      _r_a:2;
        u8                      misc_ctl:4;
        u8                      inter_sel:4;
+#else
+       u32                     inter_sel:4;
+       u32                     misc_ctl:4;
+       u32                     _r_a:2;
+       u32                     len:22;
+#endif
 };
 
 struct mvs_prd {
        /* 64-bit buffer address */
        __le64                  addr;
        /* 22-bit length */
-       struct mvs_prd_imt      im_len;
+       __le32                  im_len;
 } __attribute__ ((packed));
 
 /*
index 4519f809a8df128145b4d0bc44f9d46b51d06062..0a11bc7174ac7f16dfed725e8f1a832c8974bd03 100644 (file)
@@ -184,18 +184,6 @@ static inline void __devinit mvs_phy_hacks(struct mvs_info *mvi)
 
        /* not to halt for different port op during wideport link change */
        mvs_cw32(mvi, CMD_APP_ERR_CONFIG, 0xffefbf7d);
-
-       /* workaround for Seagate disk not-found OOB sequence, recv
-        * COMINIT before sending out COMWAKE */
-       tmp = mvs_cr32(mvi, CMD_PHY_MODE_21);
-       tmp &= 0x0000ffff;
-       tmp |= 0x00fa0000;
-       mvs_cw32(mvi, CMD_PHY_MODE_21, tmp);
-
-       tmp = mvs_cr32(mvi, CMD_PHY_TIMER);
-       tmp &= 0x1fffffff;
-       tmp |= (2U << 29);      /* 8 ms retry */
-       mvs_cw32(mvi, CMD_PHY_TIMER, tmp);
 }
 
 static inline void mvs_int_sata(struct mvs_info *mvi)
index bf7d90cfbcfc2726473dd29f36696d2af27b721f..b28ee5bd7eebc98bddf782092aea66adab023811 100644 (file)
@@ -104,6 +104,7 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id)
        struct asd_sas_phy *sas_phy = &phy->sas_phy;
 
        phy->mvi = mvi;
+       phy->port = NULL;
        init_timer(&phy->timer);
        sas_phy->enabled = (phy_id < mvi->chip->n_phy) ? 1 : 0;
        sas_phy->class = SAS;
@@ -366,7 +367,7 @@ static struct mvs_info *__devinit mvs_pci_alloc(struct pci_dev *pdev,
                                const struct pci_device_id *ent,
                                struct Scsi_Host *shost, unsigned int id)
 {
-       struct mvs_info *mvi;
+       struct mvs_info *mvi = NULL;
        struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
 
        mvi = kzalloc(sizeof(*mvi) +
index 38b47918c04733a39ecb0b103c74216a2bd5f753..31ca8fe25caee9c7cf3ccf9010b9ac624bd197df 100644 (file)
@@ -300,7 +300,10 @@ int mvs_slave_configure(struct scsi_device *sdev)
 
        if (ret)
                return ret;
-       if (dev_is_sata(dev)) {
+       if (!dev_is_sata(dev)) {
+               sas_change_queue_depth(sdev,
+                       MVS_QUEUE_SIZE,
+                       SCSI_QDEPTH_DEFAULT);
        }
        return 0;
 }
@@ -311,6 +314,7 @@ void mvs_scan_start(struct Scsi_Host *shost)
        unsigned short core_nr;
        struct mvs_info *mvi;
        struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+       struct mvs_prv_info *mvs_prv = sha->lldd_ha;
 
        core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
 
@@ -319,15 +323,17 @@ void mvs_scan_start(struct Scsi_Host *shost)
                for (i = 0; i < mvi->chip->n_phy; ++i)
                        mvs_bytes_dmaed(mvi, i);
        }
+       mvs_prv->scan_finished = 1;
 }
 
 int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time)
 {
-       /* give the phy enabling interrupt event time to come in (1s
-        * is empirically about all it takes) */
-       if (time < HZ)
+       struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+       struct mvs_prv_info *mvs_prv = sha->lldd_ha;
+
+       if (mvs_prv->scan_finished == 0)
                return 0;
-       /* Wait for discovery to finish */
+
        scsi_flush_work(shost);
        return 1;
 }
@@ -625,6 +631,9 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
        }
        if (is_tmf)
                flags |= (MCH_SSP_FR_TASK << MCH_SSP_FR_TYPE_SHIFT);
+       else
+               flags |= (MCH_SSP_FR_CMD << MCH_SSP_FR_TYPE_SHIFT);
+
        hdr->flags = cpu_to_le32(flags | (tei->n_elem << MCH_PRD_LEN_SHIFT));
        hdr->tags = cpu_to_le32(tag);
        hdr->data_len = cpu_to_le32(task->total_xfer_len);
@@ -1049,9 +1058,9 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task,
        mvs_slot_free(mvi, slot_idx);
 }
 
-static void mvs_update_wideport(struct mvs_info *mvi, int i)
+static void mvs_update_wideport(struct mvs_info *mvi, int phy_no)
 {
-       struct mvs_phy *phy = &mvi->phy[i];
+       struct mvs_phy *phy = &mvi->phy[phy_no];
        struct mvs_port *port = phy->port;
        int j, no;
 
@@ -1106,16 +1115,16 @@ static void *mvs_get_d2h_reg(struct mvs_info *mvi, int i, void *buf)
                return NULL;
 
        MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG3);
-       s[3] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i);
+       s[3] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
 
        MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG2);
-       s[2] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i);
+       s[2] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
 
        MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG1);
-       s[1] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i);
+       s[1] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
 
        MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_SATA_SIG0);
-       s[0] = MVS_CHIP_DISP->read_port_cfg_data(mvi, i);
+       s[0] = cpu_to_le32(MVS_CHIP_DISP->read_port_cfg_data(mvi, i));
 
        /* Workaround: take some ATAPI devices for ATA */
        if (((s[1] & 0x00FFFFFF) == 0x00EB1401) && (*(u8 *)&s[3] == 0x01))
@@ -1201,9 +1210,9 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st)
                if (MVS_CHIP_DISP->phy_work_around)
                        MVS_CHIP_DISP->phy_work_around(mvi, i);
        }
-       mv_dprintk("port %d attach dev info is %x\n",
+       mv_dprintk("phy %d attach dev info is %x\n",
                i + mvi->id * mvi->chip->n_phy, phy->att_dev_info);
-       mv_dprintk("port %d attach sas addr is %llx\n",
+       mv_dprintk("phy %d attach sas addr is %llx\n",
                i + mvi->id * mvi->chip->n_phy, phy->att_dev_sas_addr);
 out_done:
        if (get_st)
@@ -1228,10 +1237,10 @@ static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock)
        }
        hi = i/((struct mvs_prv_info *)sas_ha->lldd_ha)->n_phy;
        mvi = ((struct mvs_prv_info *)sas_ha->lldd_ha)->mvi[hi];
-       if (sas_port->id >= mvi->chip->n_phy)
-               port = &mvi->port[sas_port->id - mvi->chip->n_phy];
+       if (i >= mvi->chip->n_phy)
+               port = &mvi->port[i - mvi->chip->n_phy];
        else
-               port = &mvi->port[sas_port->id];
+               port = &mvi->port[i];
        if (lock)
                spin_lock_irqsave(&mvi->lock, flags);
        port->port_attached = 1;
@@ -1260,7 +1269,7 @@ static void mvs_port_notify_deformed(struct asd_sas_phy *sas_phy, int lock)
                        return;
        }
        list_for_each_entry(dev, &port->dev_list, dev_list_node)
-               mvs_do_release_task(phy->mvi, phy_no, NULL);
+               mvs_do_release_task(phy->mvi, phy_no, dev);
 
 }
 
@@ -1324,6 +1333,7 @@ int mvs_dev_found_notify(struct domain_device *dev, int lock)
        mvi_device->dev_status = MVS_DEV_NORMAL;
        mvi_device->dev_type = dev->dev_type;
        mvi_device->mvi_info = mvi;
+       mvi_device->sas_device = dev;
        if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) {
                int phy_id;
                u8 phy_num = parent_dev->ex_dev.num_phys;
@@ -1375,6 +1385,7 @@ void mvs_dev_gone_notify(struct domain_device *dev)
                mv_dprintk("found dev has gone.\n");
        }
        dev->lldd_dev = NULL;
+       mvi_dev->sas_device = NULL;
 
        spin_unlock_irqrestore(&mvi->lock, flags);
 }
@@ -1455,7 +1466,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev,
                }
 
                wait_for_completion(&task->completion);
-               res = -TMF_RESP_FUNC_FAILED;
+               res = TMF_RESP_FUNC_FAILED;
                /* Even TMF timed out, return direct. */
                if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
                        if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
@@ -1505,11 +1516,10 @@ static int mvs_debug_issue_ssp_tmf(struct domain_device *dev,
                                u8 *lun, struct mvs_tmf_task *tmf)
 {
        struct sas_ssp_task ssp_task;
-       DECLARE_COMPLETION_ONSTACK(completion);
        if (!(dev->tproto & SAS_PROTOCOL_SSP))
                return TMF_RESP_FUNC_ESUPP;
 
-       strncpy((u8 *)&ssp_task.LUN, lun, 8);
+       memcpy(ssp_task.LUN, lun, 8);
 
        return mvs_exec_internal_tmf_task(dev, &ssp_task,
                                sizeof(ssp_task), tmf);
@@ -1533,7 +1543,7 @@ static int mvs_debug_I_T_nexus_reset(struct domain_device *dev)
 int mvs_lu_reset(struct domain_device *dev, u8 *lun)
 {
        unsigned long flags;
-       int i, phyno[WIDE_PORT_MAX_PHY], num , rc = TMF_RESP_FUNC_FAILED;
+       int rc = TMF_RESP_FUNC_FAILED;
        struct mvs_tmf_task tmf_task;
        struct mvs_device * mvi_dev = dev->lldd_dev;
        struct mvs_info *mvi = mvi_dev->mvi_info;
@@ -1542,10 +1552,8 @@ int mvs_lu_reset(struct domain_device *dev, u8 *lun)
        mvi_dev->dev_status = MVS_DEV_EH;
        rc = mvs_debug_issue_ssp_tmf(dev, lun, &tmf_task);
        if (rc == TMF_RESP_FUNC_COMPLETE) {
-               num = mvs_find_dev_phyno(dev, phyno);
                spin_lock_irqsave(&mvi->lock, flags);
-               for (i = 0; i < num; i++)
-                       mvs_release_task(mvi, dev);
+               mvs_release_task(mvi, dev);
                spin_unlock_irqrestore(&mvi->lock, flags);
        }
        /* If failed, fall-through I_T_Nexus reset */
@@ -1563,6 +1571,8 @@ int mvs_I_T_nexus_reset(struct domain_device *dev)
 
        if (mvi_dev->dev_status != MVS_DEV_EH)
                return TMF_RESP_FUNC_COMPLETE;
+       else
+               mvi_dev->dev_status = MVS_DEV_NORMAL;
        rc = mvs_debug_I_T_nexus_reset(dev);
        mv_printk("%s for device[%x]:rc= %d\n",
                __func__, mvi_dev->device_id, rc);
@@ -1606,9 +1616,6 @@ int mvs_query_task(struct sas_task *task)
                case TMF_RESP_FUNC_FAILED:
                case TMF_RESP_FUNC_COMPLETE:
                        break;
-               default:
-                       rc = TMF_RESP_FUNC_COMPLETE;
-                       break;
                }
        }
        mv_printk("%s:rc= %d\n", __func__, rc);
@@ -1628,8 +1635,8 @@ int mvs_abort_task(struct sas_task *task)
        u32 tag;
 
        if (!mvi_dev) {
-               mv_printk("%s:%d TMF_RESP_FUNC_FAILED\n", __func__, __LINE__);
-               rc = TMF_RESP_FUNC_FAILED;
+               mv_printk("Device has removed\n");
+               return TMF_RESP_FUNC_FAILED;
        }
 
        mvi = mvi_dev->mvi_info;
@@ -1677,22 +1684,15 @@ int mvs_abort_task(struct sas_task *task)
                /* to do free register_set */
                if (SATA_DEV == dev->dev_type) {
                        struct mvs_slot_info *slot = task->lldd_task;
-                       struct task_status_struct *tstat;
                        u32 slot_idx = (u32)(slot - mvi->slot_info);
-                       tstat = &task->task_status;
-                       mv_dprintk(KERN_DEBUG "mv_abort_task() mvi=%p task=%p "
+                       mv_dprintk("mvs_abort_task() mvi=%p task=%p "
                                   "slot=%p slot_idx=x%x\n",
                                   mvi, task, slot, slot_idx);
-                       tstat->stat = SAS_ABORTED_TASK;
-                       if (mvi_dev && mvi_dev->running_req)
-                               mvi_dev->running_req--;
-                       if (sas_protocol_ata(task->task_proto))
-                               mvs_free_reg_set(mvi, mvi_dev);
+                       mvs_tmf_timedout((unsigned long)task);
                        mvs_slot_task_free(mvi, task, slot, slot_idx);
-                       return -1;
+                       rc = TMF_RESP_FUNC_COMPLETE;
+                       goto out;
                }
-       } else {
-               /* SMP */
 
        }
 out:
@@ -1813,7 +1813,7 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
 {
        struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
        int stat;
-       u32 err_dw0 = le32_to_cpu(*(u32 *) (slot->response));
+       u32 err_dw0 = le32_to_cpu(*(u32 *)slot->response);
        u32 err_dw1 = le32_to_cpu(*((u32 *)slot->response + 1));
        u32 tfs = 0;
        enum mvs_port_type type = PORT_TYPE_SAS;
@@ -1847,10 +1847,8 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
        case SAS_PROTOCOL_STP:
        case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
        {
-               if (err_dw0 == 0x80400002)
-                       mv_printk("find reserved error, why?\n");
-
                task->ata_task.use_ncq = 0;
+               stat = SAS_PROTO_RESPONSE;
                mvs_sata_done(mvi, task, slot_idx, err_dw0);
        }
                break;
@@ -1912,6 +1910,9 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
 
        /* error info record present */
        if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) {
+               mv_dprintk("port %d slot %d rx_desc %X has error info"
+                       "%016llX.\n", slot->port->sas_port.id, slot_idx,
+                        rx_desc, (u64)(*(u64 *)slot->response));
                tstat->stat = mvs_slot_err(mvi, task, slot_idx);
                tstat->resp = SAS_TASK_COMPLETE;
                goto out;
@@ -1973,8 +1974,7 @@ out:
        spin_unlock(&mvi->lock);
        if (task->task_done)
                task->task_done(task);
-       else
-               mv_dprintk("why has not task_done.\n");
+
        spin_lock(&mvi->lock);
 
        return sts;
@@ -2115,9 +2115,10 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
        struct mvs_phy *phy = &mvi->phy[phy_no];
 
        phy->irq_status = MVS_CHIP_DISP->read_port_irq_stat(mvi, phy_no);
-       mv_dprintk("port %d ctrl sts=0x%X.\n", phy_no+mvi->id*mvi->chip->n_phy,
+       MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status);
+       mv_dprintk("phy %d ctrl sts=0x%08X.\n", phy_no+mvi->id*mvi->chip->n_phy,
                MVS_CHIP_DISP->read_phy_ctl(mvi, phy_no));
-       mv_dprintk("Port %d irq sts = 0x%X\n", phy_no+mvi->id*mvi->chip->n_phy,
+       mv_dprintk("phy %d irq sts = 0x%08X\n", phy_no+mvi->id*mvi->chip->n_phy,
                phy->irq_status);
 
        /*
@@ -2126,11 +2127,12 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
        */
 
        if (phy->irq_status & PHYEV_DCDR_ERR) {
-               mv_dprintk("port %d STP decoding error.\n",
+               mv_dprintk("phy %d STP decoding error.\n",
                phy_no + mvi->id*mvi->chip->n_phy);
        }
 
        if (phy->irq_status & PHYEV_POOF) {
+               mdelay(500);
                if (!(phy->phy_event & PHY_PLUG_OUT)) {
                        int dev_sata = phy->phy_type & PORT_TYPE_SATA;
                        int ready;
@@ -2141,10 +2143,6 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
                                (void *)(unsigned long)phy_no,
                                PHY_PLUG_EVENT);
                        ready = mvs_is_phy_ready(mvi, phy_no);
-                       if (!ready)
-                               mv_dprintk("phy%d Unplug Notice\n",
-                                       phy_no +
-                                       mvi->id * mvi->chip->n_phy);
                        if (ready || dev_sata) {
                                if (MVS_CHIP_DISP->stp_reset)
                                        MVS_CHIP_DISP->stp_reset(mvi,
@@ -2164,7 +2162,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
                if (phy->timer.function == NULL) {
                        phy->timer.data = (unsigned long)phy;
                        phy->timer.function = mvs_sig_time_out;
-                       phy->timer.expires = jiffies + 10*HZ;
+                       phy->timer.expires = jiffies + 5*HZ;
                        add_timer(&phy->timer);
                }
        }
@@ -2198,12 +2196,11 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
                                phy_no + mvi->id*mvi->chip->n_phy);
                }
        } else if (phy->irq_status & PHYEV_BROAD_CH) {
-               mv_dprintk("port %d broadcast change.\n",
+               mv_dprintk("phy %d broadcast change.\n",
                        phy_no + mvi->id*mvi->chip->n_phy);
                mvs_handle_event(mvi, (void *)(unsigned long)phy_no,
                                EXP_BRCT_CHG);
        }
-       MVS_CHIP_DISP->write_port_irq_stat(mvi, phy_no, phy->irq_status);
 }
 
 int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
index 428b00a36482f46587d466a21d268b7e62f0860b..25fae4f6aff2a747459aa40b4edb94e5e96871a8 100644 (file)
@@ -417,7 +417,8 @@ struct mvs_info {
 struct mvs_prv_info{
        u8 n_host;
        u8 n_phy;
-       u16 reserve;
+       u8 scan_finished;
+       u8 reserve;
        struct mvs_info *mvi[2];
 };