aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-12-11 12:15:31 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-16 10:13:22 -0500
commit33480a0ede8dcc7e6483054279008f972bd56fd3 (patch)
treedb0f1ad9f3e7ba78a7f12d3a2ed3dc0e7534ac67 /drivers/ata
parentc10340aca270abb141154cd93dcf1be0b92143fc (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.c14
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/**