Commit 93e2618e authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 0706efd6
...@@ -63,6 +63,21 @@ enum { ...@@ -63,6 +63,21 @@ enum {
SIL24_HOST_BAR = 0, SIL24_HOST_BAR = 0,
SIL24_PORT_BAR = 2, 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) * Global controller registers (128 bytes @ BAR0)
*/ */
...@@ -247,13 +262,13 @@ enum { ...@@ -247,13 +262,13 @@ enum {
struct sil24_ata_block { struct sil24_ata_block {
struct sil24_prb prb; struct sil24_prb prb;
struct sil24_sge sge[LIBATA_MAX_PRD]; struct sil24_sge sge[SIL24_MAX_SGE];
}; };
struct sil24_atapi_block { struct sil24_atapi_block {
struct sil24_prb prb; struct sil24_prb prb;
u8 cdb[16]; u8 cdb[16];
struct sil24_sge sge[LIBATA_MAX_PRD - 1]; struct sil24_sge sge[SIL24_MAX_SGE];
}; };
union sil24_cmd_block { union sil24_cmd_block {
...@@ -378,7 +393,7 @@ static struct scsi_host_template sil24_sht = { ...@@ -378,7 +393,7 @@ static struct scsi_host_template sil24_sht = {
.change_queue_depth = ata_scsi_change_queue_depth, .change_queue_depth = ata_scsi_change_queue_depth,
.can_queue = SIL24_MAX_CMDS, .can_queue = SIL24_MAX_CMDS,
.this_id = ATA_SHT_THIS_ID, .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD, .sg_tablesize = SIL24_MAX_SGE,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN, .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED, .emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING, .use_clustering = ATA_SHT_USE_CLUSTERING,
...@@ -1284,6 +1299,7 @@ static void sil24_init_controller(struct ata_host *host) ...@@ -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) 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; static int printed_version;
struct ata_port_info pi = sil24_port_info[ent->driver_data]; struct ata_port_info pi = sil24_port_info[ent->driver_data];
const struct ata_port_info *ppi[] = { &pi, NULL }; 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) ...@@ -1292,6 +1308,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
int i, rc; int i, rc;
u32 tmp; 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++) if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment