diff options
author | Tejun Heo <htejun@gmail.com> | 2006-12-11 12:15:31 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-16 10:13:22 -0500 |
commit | 33480a0ede8dcc7e6483054279008f972bd56fd3 (patch) | |
tree | db0f1ad9f3e7ba78a7f12d3a2ed3dc0e7534ac67 /drivers/ata | |
parent | c10340aca270abb141154cd93dcf1be0b92143fc (diff) |
[PATCH] libata: don't initialize sg in ata_exec_internal() if DMA_NONE (take #2)
Calling sg_init_one() with NULL buf causes oops on certain
configurations. Don't initialize sg in ata_exec_internal() if
DMA_NONE and make the function complain if @buf is NULL when dma_dir
isn't DMA_NONE. While at it, fix comment.
The problem is discovered and initial patch was submitted by Arnd
Bergmann.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 011c0a8a2dcc..0d51d13b16bf 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1332,7 +1332,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, | |||
1332 | } | 1332 | } |
1333 | 1333 | ||
1334 | /** | 1334 | /** |
1335 | * ata_exec_internal_sg - execute libata internal command | 1335 | * ata_exec_internal - execute libata internal command |
1336 | * @dev: Device to which the command is sent | 1336 | * @dev: Device to which the command is sent |
1337 | * @tf: Taskfile registers for the command and the result | 1337 | * @tf: Taskfile registers for the command and the result |
1338 | * @cdb: CDB for packet command | 1338 | * @cdb: CDB for packet command |
@@ -1353,11 +1353,17 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
1353 | struct ata_taskfile *tf, const u8 *cdb, | 1353 | struct ata_taskfile *tf, const u8 *cdb, |
1354 | int dma_dir, void *buf, unsigned int buflen) | 1354 | int dma_dir, void *buf, unsigned int buflen) |
1355 | { | 1355 | { |
1356 | struct scatterlist sg; | 1356 | struct scatterlist *psg = NULL, sg; |
1357 | unsigned int n_elem = 0; | ||
1357 | 1358 | ||
1358 | sg_init_one(&sg, buf, buflen); | 1359 | if (dma_dir != DMA_NONE) { |
1360 | WARN_ON(!buf); | ||
1361 | sg_init_one(&sg, buf, buflen); | ||
1362 | psg = &sg; | ||
1363 | n_elem++; | ||
1364 | } | ||
1359 | 1365 | ||
1360 | return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1); | 1366 | return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem); |
1361 | } | 1367 | } |
1362 | 1368 | ||
1363 | /** | 1369 | /** |