diff options
| author | Tejun Heo <htejun@gmail.com> | 2007-11-22 04:46:57 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2007-11-23 19:23:55 -0500 |
| commit | 93e2618e0cee1f5b5a4cfc1b7521939318dbf5bb (patch) | |
| tree | e535579b3e39c603f81e0144dbf744d0204c6975 | |
| parent | 0706efd61edfcf958c2c19669aa65c2180ec3ba0 (diff) | |
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 <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
| -rw-r--r-- | 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 187dcb02c681..96fd5260446d 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
| @@ -63,6 +63,21 @@ enum { | |||
| 63 | SIL24_HOST_BAR = 0, | 63 | SIL24_HOST_BAR = 0, |
| 64 | SIL24_PORT_BAR = 2, | 64 | SIL24_PORT_BAR = 2, |
| 65 | 65 | ||
| 66 | /* sil24 fetches in chunks of 64bytes. The first block | ||
| 67 | * contains the PRB and two SGEs. From the second block, it's | ||
| 68 | * consisted of four SGEs and called SGT. Calculate the | ||
| 69 | * number of SGTs that fit into one page. | ||
| 70 | */ | ||
| 71 | SIL24_PRB_SZ = sizeof(struct sil24_prb) | ||
| 72 | + 2 * sizeof(struct sil24_sge), | ||
| 73 | SIL24_MAX_SGT = (PAGE_SIZE - SIL24_PRB_SZ) | ||
| 74 | / (4 * sizeof(struct sil24_sge)), | ||
| 75 | |||
| 76 | /* This will give us one unused SGEs for ATA. This extra SGE | ||
| 77 | * will be used to store CDB for ATAPI devices. | ||
| 78 | */ | ||
| 79 | SIL24_MAX_SGE = 4 * SIL24_MAX_SGT + 1, | ||
| 80 | |||
| 66 | /* | 81 | /* |
| 67 | * Global controller registers (128 bytes @ BAR0) | 82 | * Global controller registers (128 bytes @ BAR0) |
| 68 | */ | 83 | */ |
| @@ -247,13 +262,13 @@ enum { | |||
| 247 | 262 | ||
| 248 | struct sil24_ata_block { | 263 | struct sil24_ata_block { |
| 249 | struct sil24_prb prb; | 264 | struct sil24_prb prb; |
| 250 | struct sil24_sge sge[LIBATA_MAX_PRD]; | 265 | struct sil24_sge sge[SIL24_MAX_SGE]; |
| 251 | }; | 266 | }; |
| 252 | 267 | ||
| 253 | struct sil24_atapi_block { | 268 | struct sil24_atapi_block { |
| 254 | struct sil24_prb prb; | 269 | struct sil24_prb prb; |
| 255 | u8 cdb[16]; | 270 | u8 cdb[16]; |
| 256 | struct sil24_sge sge[LIBATA_MAX_PRD - 1]; | 271 | struct sil24_sge sge[SIL24_MAX_SGE]; |
| 257 | }; | 272 | }; |
| 258 | 273 | ||
| 259 | union sil24_cmd_block { | 274 | union sil24_cmd_block { |
| @@ -378,7 +393,7 @@ static struct scsi_host_template sil24_sht = { | |||
| 378 | .change_queue_depth = ata_scsi_change_queue_depth, | 393 | .change_queue_depth = ata_scsi_change_queue_depth, |
| 379 | .can_queue = SIL24_MAX_CMDS, | 394 | .can_queue = SIL24_MAX_CMDS, |
| 380 | .this_id = ATA_SHT_THIS_ID, | 395 | .this_id = ATA_SHT_THIS_ID, |
| 381 | .sg_tablesize = LIBATA_MAX_PRD, | 396 | .sg_tablesize = SIL24_MAX_SGE, |
| 382 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 397 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
| 383 | .emulated = ATA_SHT_EMULATED, | 398 | .emulated = ATA_SHT_EMULATED, |
| 384 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 399 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
| @@ -1284,6 +1299,7 @@ static void sil24_init_controller(struct ata_host *host) | |||
| 1284 | 1299 | ||
| 1285 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1300 | static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 1286 | { | 1301 | { |
| 1302 | extern int __MARKER__sil24_cmd_block_is_sized_wrongly; | ||
| 1287 | static int printed_version; | 1303 | static int printed_version; |
| 1288 | struct ata_port_info pi = sil24_port_info[ent->driver_data]; | 1304 | struct ata_port_info pi = sil24_port_info[ent->driver_data]; |
| 1289 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 1305 | 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 | int i, rc; | 1308 | int i, rc; |
| 1293 | u32 tmp; | 1309 | u32 tmp; |
| 1294 | 1310 | ||
| 1311 | /* cause link error if sil24_cmd_block is sized wrongly */ | ||
| 1312 | if (sizeof(union sil24_cmd_block) != PAGE_SIZE) | ||
| 1313 | __MARKER__sil24_cmd_block_is_sized_wrongly = 1; | ||
| 1314 | |||
| 1295 | if (!printed_version++) | 1315 | if (!printed_version++) |
| 1296 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1316 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
| 1297 | 1317 | ||
