Re: [PATCH] Marvell 6440 SAS/SATA driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



mvsas : Fixed coding problem

Signed-off-by: Ke Wei <kewei@xxxxxxxxxxx>
---
 drivers/scsi/mvsas.c |   61 +++++++++++++++++++++++++++----------------------
 1 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c
index 321be21..3bf009b 100755
--- a/drivers/scsi/mvsas.c
+++ b/drivers/scsi/mvsas.c
@@ -55,11 +55,11 @@
 
 /* offset for D2H FIS in the Received FIS List Structure */
 #define SATA_RECEIVED_D2H_FIS(reg_set) \
-	(mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x40)
+	((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x40)
 #define SATA_RECEIVED_PIO_FIS(reg_set) \
-	(mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x20)
+	((void *) mvi->rx_fis + 0x400 + 0x100 * reg_set + 0x20)
 #define UNASSOC_D2H_FIS(id) \
-	(mvi->rx_fis + 0x100 * id)
+	((void *) mvi->rx_fis + 0x100 * id)
 
 /* driver compile-time configuration */
 enum driver_configuration {
@@ -553,17 +553,16 @@ struct mvs_phy {
 	struct mvs_port		*port;
 	struct asd_sas_phy	sas_phy;
 	struct sas_identify identify;
-	__le32		dev_info;
-	__le64		dev_sas_addr;
-	__le32		att_dev_info;
-	__le64		att_dev_sas_addr;
+	u64		dev_sas_addr;
+	u64		att_dev_sas_addr;
+	u32		att_dev_info;
+	u32		dev_info;
 	u32		type;
-	__le32		phy_status;
-	__le32		irq_status;
-	u8		wide_port_phymap;
+	u32		phy_status;
+	u32		irq_status;
 	u32		frame_rcvd_size;
 	u8		frame_rcvd[32];
-
+	u8		wide_port_phymap;
 };
 
 struct mvs_info {
@@ -586,7 +585,7 @@ struct mvs_info {
 	dma_addr_t		rx_dma;
 	u32			rx_cons;	/* RX consumer idx */
 
-	void			*rx_fis;	/* RX'd FIS area */
+	__le32			*rx_fis;	/* RX'd FIS area */
 	dma_addr_t		rx_fis_dma;
 
 	struct mvs_cmd_hdr	*slot;	/* DMA command header slots */
@@ -624,7 +623,6 @@ static void mvs_write_port_vsr_data(struct mvs_info *mvi, u32 port, u32 val);
 static void mvs_write_port_vsr_addr(struct mvs_info *mvi, u32 port, u32 addr);
 static u32 mvs_read_port_irq_stat(struct mvs_info *mvi, u32 port);
 static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val);
-static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port);
 static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val);
 
 static int mvs_scan_finished(struct Scsi_Host *, unsigned long);
@@ -705,8 +703,7 @@ static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag,
 	else
 		len_ct = MVS_SSP_CMD_SZ;
 
-	offset =
-	    len_ct + MVS_OAF_SZ +
+	offset = len_ct + MVS_OAF_SZ +
 	    sizeof(struct mvs_prd) * mvi->slot_info[tag].n_elem;
 	dev_printk(KERN_DEBUG, &pdev->dev, "+---->Status buffer :\n");
 	mvs_hexdump(32, (u8 *) mvi->slot_info[tag].response,
@@ -792,21 +789,27 @@ static void mvs_hba_cq_dump(struct mvs_info *mvi)
 #endif
 }
 
-static void mvs_hba_interrupt_enable(struct mvs_info *mvi, int enable)
+#if 0
+static void mvs_hba_interrupt_enable(struct mvs_info *mvi)
 {
 	void __iomem *regs = mvi->regs;
 	u32 tmp;
-	unsigned long flags;
 
-	spin_lock_irqsave(&mvi->lock, flags);
 	tmp = mr32(GBL_CTL);
 
-	if (enable)
-		mw32(GBL_CTL, tmp | INT_EN);
-	else
-		mw32(GBL_CTL, tmp & ~INT_EN);
-	spin_unlock_irqrestore(&mvi->lock, flags);
+	mw32(GBL_CTL, tmp | INT_EN);
+}
+
+static void mvs_hba_interrupt_disable(struct mvs_info *mvi)
+{
+	void __iomem *regs = mvi->regs;
+	u32 tmp;
+
+	tmp = mr32(GBL_CTL);
+
+	mw32(GBL_CTL, tmp & ~INT_EN);
 }
+#endif
 
 static int mvs_int_rx(struct mvs_info *mvi, bool self_clear);
 
@@ -1345,6 +1348,7 @@ err_out:
 	return rc;
 }
 
+#if 0
 static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port)
 {
 	void __iomem *regs = mvi->regs;
@@ -1364,6 +1368,7 @@ static void mvs_free_reg_set(struct mvs_info *mvi, struct mvs_port *port)
 
 	port->taskfileset = MVS_ID_NOT_MAPPED;
 }
+#endif
 
 static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port)
 {
@@ -2122,10 +2127,12 @@ static void mvs_write_port_irq_stat(struct mvs_info *mvi, u32 port, u32 val)
 	mvs_write_port(mvi, MVS_P0_INT_STAT, MVS_P4_INT_STAT, port, val);
 }
 
+#if 0
 static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port)
 {
 	return mvs_read_port(mvi, MVS_P0_INT_MASK, MVS_P4_INT_MASK, port);
 }
+#endif
 
 static void mvs_write_port_irq_mask(struct mvs_info *mvi, u32 port, u32 val)
 {
@@ -2258,17 +2265,17 @@ static void __devinit mvs_update_phyinfo(struct mvs_info *mvi, int i)
 {
 	struct mvs_phy *phy = &mvi->phy[i];
 	u32 tmp;
-	__le64 tmp64;
+	u64 tmp64;
 	struct pci_dev *pdev = mvi->pdev;
 
 	mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY);
 	phy->dev_info = mvs_read_port_cfg_data(mvi, i);
 
 	mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_HI);
-	phy->dev_sas_addr = (__le64) mvs_read_port_cfg_data(mvi, i) << 32;
+	phy->dev_sas_addr = (u64) mvs_read_port_cfg_data(mvi, i) << 32;
 
 	mvs_write_port_cfg_addr(mvi, i, PHYR_ADDR_LO);
-	phy->dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);	/* le */
+	phy->dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
 
 	phy->phy_status = mvs_read_phy_ctl(mvi, i);
 
@@ -2286,7 +2293,7 @@ static void __devinit mvs_update_phyinfo(struct mvs_info *mvi, int i)
 
 		mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI);
 		phy->att_dev_sas_addr =
-			(__le64) mvs_read_port_cfg_data(mvi, i) << 32;
+				(u64) mvs_read_port_cfg_data(mvi, i) << 32;
 
 		mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO);
 		phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i);
-- 
1.5.4.rc4

> I really don't think you should be doing this.  That single ring governs
> all the potential tag slots for everything in this device.  If you do a
> simple head tail allocation, what can happen is that you get a slow tag
> (attached to a format command, or a tape command) and then the ring head
> will hit the slow tag and the entire device will halt.  I think you need
> a bitmap based allocation algorithm to ensure that if you have a free
> tag anywhere, you'll use it.
> 
> If you look at the aic94xx index functions in aic94xx_hwi.h you'll see
> asd_tc_index_get() and asd_tc_index_release() doing exactly what you
> want with the native linux bitmap functions (the aic also uses a single
> issue queue with indexes into it).

I don't think we need to make use of a bitmap based allocation algorithm.
My algorithm is a simple non-blocking scheduling. Some faster tag may
be free in advance, so ring will alloc a tag number which has been
stored in mvi->tags array instead of waiting to hit the slow tag. 

I think that the bitmap based allocation algorithm try to poll and find
the first zero bit. So process may be slow. 

pls point out anything wrong.

On Fri, Jan 25, 2008 at 04:39:29PM -0600, James Bottomley wrote:
> On Sat, 2008-01-26 at 00:43 +0800, Ke Wei wrote:
> 
> >  struct mvs_phy {
> >         struct mvs_port         *port;
> >         struct asd_sas_phy      sas_phy;
> > +       struct sas_identify identify;
> > +       __le32          dev_info;
> > +       __le64          dev_sas_addr;
> > +       __le32          att_dev_info;
> > +       __le64          att_dev_sas_addr;
> > +       u32             type;
> > +       __le32          phy_status;
> > +       __le32          irq_status;
> > +       u8              wide_port_phymap;
> > +       u32             frame_rcvd_size;
> > +       u8              frame_rcvd[32];
> >  
> > -       u8                      frame_rcvd[24 + 1024];
> >  };
> 
> These __le quantites don't look right ... they're all read in by readl,
> which will convert little endian to CPU anyway.
> 
> 
> > @@ -437,27 +586,55 @@ struct mvs_info {
> >         dma_addr_t              rx_dma;
> >         u32                     rx_cons;        /* RX consumer idx */
> >  
> > -       __le32                  *rx_fis;        /* RX'd FIS area */
> > +       void                    *rx_fis;        /* RX'd FIS area */
> 
> Now the received FIS, on the other hand, provided you're storing it in
> wire format (which you look to be) *is* little endian data by definition
> in the ATA spec.
> 
> 
> > -static void mvs_tag_clear(struct mvs_info *mvi, unsigned int tag)
> > +static void mvs_tag_clear(struct mvs_info *mvi, u32 tag)
> >  {
> > -       mvi->tags[tag / sizeof(unsigned long)] &=
> > -               ~(1UL << (tag % sizeof(unsigned long)));
> > +       mvi->tag_in = (mvi->tag_in + 1) & (MVS_SLOTS - 1);
> > +       mvi->tags[mvi->tag_in] = tag;
> >  }
> >  
> > -static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag)
> > +static void mvs_tag_free(struct mvs_info *mvi, u32 tag)
> >  {
> > -       mvi->tags[tag / sizeof(unsigned long)] |=
> > -               (1UL << (tag % sizeof(unsigned long)));
> > +       mvi->tag_out = (mvi->tag_out - 1) & (MVS_SLOTS - 1);
> >  }
> >  
> > -static bool mvs_tag_test(struct mvs_info *mvi, unsigned int tag)
> > +static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out)
> >  {
> > -       return mvi->tags[tag / sizeof(unsigned long)] &
> > -               (1UL << (tag % sizeof(unsigned long)));
> > +       if (mvi->tag_out != mvi->tag_in) {
> > +               *tag_out = mvi->tags[mvi->tag_out];
> > +               mvi->tag_out = (mvi->tag_out + 1) & (MVS_SLOTS - 1);
> > +               return 0;
> > +       }
> > +       return -EBUSY;
> 
> I really don't think you should be doing this.  That single ring governs
> all the potential tag slots for everything in this device.  If you do a
> simple head tail allocation, what can happen is that you get a slow tag
> (attached to a format command, or a tape command) and then the ring head
> will hit the slow tag and the entire device will halt.  I think you need
> a bitmap based allocation algorithm to ensure that if you have a free
> tag anywhere, you'll use it.
> 
> If you look at the aic94xx index functions in aic94xx_hwi.h you'll see
> asd_tc_index_get() and asd_tc_index_release() doing exactly what you
> want with the native linux bitmap functions (the aic also uses a single
> issue queue with indexes into it).
> 
> James
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux