Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=93e2618e0cee1f5b5a4cfc1b7521939318dbf5bb
Commit:     93e2618e0cee1f5b5a4cfc1b7521939318dbf5bb
Parent:     0706efd61edfcf958c2c19669aa65c2180ec3ba0
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Thu Nov 22 18:46:57 2007 +0900
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Fri Nov 23 19:23:55 2007 -0500

    sata_sil24: fix sg table sizing
    
    sil24 unnecessarily used LIBATA_MAX_PRD and ATAPI sg table was short
    by one entry which might cause very obscure problems.  This patch
    updates sg table sizing such that
    
    * One full page is used for PRB + sg table.  On 4k page,
      this results in 253 sg's.
    
    * Make ATAPI sg block properly sized.
    
    * Make build fail if command block size doesn't equal PAGE_SIZE.
    
    Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/ata/sata_sil24.c |   26 +++++++++++++++++++++++---
 1 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 187dcb0..96fd526 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -63,6 +63,21 @@ enum {
        SIL24_HOST_BAR          = 0,
        SIL24_PORT_BAR          = 2,
 
+       /* sil24 fetches in chunks of 64bytes.  The first block
+        * contains the PRB and two SGEs.  From the second block, it's
+        * consisted of four SGEs and called SGT.  Calculate the
+        * number of SGTs that fit into one page.
+        */
+       SIL24_PRB_SZ            = sizeof(struct sil24_prb)
+                                 + 2 * sizeof(struct sil24_sge),
+       SIL24_MAX_SGT           = (PAGE_SIZE - SIL24_PRB_SZ)
+                                 / (4 * sizeof(struct sil24_sge)),
+
+       /* This will give us one unused SGEs for ATA.  This extra SGE
+        * will be used to store CDB for ATAPI devices.
+        */
+       SIL24_MAX_SGE           = 4 * SIL24_MAX_SGT + 1,
+
        /*
         * Global controller registers (128 bytes @ BAR0)
         */
@@ -247,13 +262,13 @@ enum {
 
 struct sil24_ata_block {
        struct sil24_prb prb;
-       struct sil24_sge sge[LIBATA_MAX_PRD];
+       struct sil24_sge sge[SIL24_MAX_SGE];
 };
 
 struct sil24_atapi_block {
        struct sil24_prb prb;
        u8 cdb[16];
-       struct sil24_sge sge[LIBATA_MAX_PRD - 1];
+       struct sil24_sge sge[SIL24_MAX_SGE];
 };
 
 union sil24_cmd_block {
@@ -378,7 +393,7 @@ static struct scsi_host_template sil24_sht = {
        .change_queue_depth     = ata_scsi_change_queue_depth,
        .can_queue              = SIL24_MAX_CMDS,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = LIBATA_MAX_PRD,
+       .sg_tablesize           = SIL24_MAX_SGE,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
@@ -1284,6 +1299,7 @@ static void sil24_init_controller(struct ata_host *host)
 
 static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id 
*ent)
 {
+       extern int __MARKER__sil24_cmd_block_is_sized_wrongly;
        static int printed_version;
        struct ata_port_info pi = sil24_port_info[ent->driver_data];
        const struct ata_port_info *ppi[] = { &pi, NULL };
@@ -1292,6 +1308,10 @@ static int sil24_init_one(struct pci_dev *pdev, const 
struct pci_device_id *ent)
        int i, rc;
        u32 tmp;
 
+       /* cause link error if sil24_cmd_block is sized wrongly */
+       if (sizeof(union sil24_cmd_block) != PAGE_SIZE)
+               __MARKER__sil24_cmd_block_is_sized_wrongly = 1;
+
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to