From: Tejun Heo 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 Cc: Arnd Bergmann Signed-off-by: Andrew Morton --- drivers/ata/libata-core.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff -puN drivers/ata/libata-core.c~libata-dont-initialize-sg-in-ata_exec_internal-if-dma_none-take-2 drivers/ata/libata-core.c --- a/drivers/ata/libata-core.c~libata-dont-initialize-sg-in-ata_exec_internal-if-dma_none-take-2 +++ a/drivers/ata/libata-core.c @@ -1168,7 +1168,7 @@ void ata_qc_complete_internal(struct ata } /** - * ata_exec_internal_sg - execute libata internal command + * ata_exec_internal - execute libata internal command * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result * @cdb: CDB for packet command @@ -1357,11 +1357,17 @@ unsigned ata_exec_internal(struct ata_de struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen) { - struct scatterlist sg; + struct scatterlist *psg = NULL, sg; + unsigned int n_elem = 0; - sg_init_one(&sg, buf, buflen); + if (dma_dir != DMA_NONE) { + WARN_ON(!buf); + sg_init_one(&sg, buf, buflen); + psg = &sg; + n_elem++; + } - return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1); + return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem); } /** _