aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-24 18:22:54 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-03-24 18:22:54 -0400
commit2f40c9b0b65b5635e2e13dfa068bd56fe7a8ff98 (patch)
treef2ac83e1b59fb7cefde88455882817a2af99dbe4 /drivers/ide
parentd45b70ab9bbf1a46ae52972d532f9e267b8d39d9 (diff)
ide: fix kmalloc() failure handling in ide_driveid_update()
* Doing kmalloc() in the middle of command execution is not only ugly but leaves drive waiting to send data on kmalloc() failure. Fix it. While at it: * Unify error code paths. * Fixup error message to be more useful and add missing KERN_ERR level. * Rename 'stat' variable to 's'. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-iops.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index e0cfa2d2acc7..a955483d2404 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -293,7 +293,12 @@ int ide_driveid_update(ide_drive_t *drive)
293 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 293 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
294 u16 *id; 294 u16 *id;
295 unsigned long flags; 295 unsigned long flags;
296 u8 stat; 296 int rc;
297 u8 uninitialized_var(s);
298
299 id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
300 if (id == NULL)
301 return 0;
297 302
298 /* 303 /*
299 * Re-read drive->id for possible DMA mode 304 * Re-read drive->id for possible DMA mode
@@ -306,25 +311,21 @@ int ide_driveid_update(ide_drive_t *drive)
306 tp_ops->exec_command(hwif, ATA_CMD_ID_ATA); 311 tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);
307 312
308 if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) { 313 if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
309 SELECT_MASK(drive, 0); 314 rc = 1;
310 return 0; 315 goto out_err;
311 } 316 }
312 317
313 msleep(50); /* wait for IRQ and ATA_DRQ */ 318 msleep(50); /* wait for IRQ and ATA_DRQ */
314 stat = tp_ops->read_status(hwif);
315 319
316 if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) { 320 s = tp_ops->read_status(hwif);
317 SELECT_MASK(drive, 0); 321
318 printk("%s: CHECK for good STATUS\n", drive->name); 322 if (!OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
319 return 0; 323 rc = 2;
324 goto out_err;
320 } 325 }
326
321 local_irq_save(flags); 327 local_irq_save(flags);
322 SELECT_MASK(drive, 0); 328 SELECT_MASK(drive, 0);
323 id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
324 if (!id) {
325 local_irq_restore(flags);
326 return 0;
327 }
328 tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); 329 tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
329 (void)tp_ops->read_status(hwif); /* clear drive IRQ */ 330 (void)tp_ops->read_status(hwif); /* clear drive IRQ */
330 local_irq_enable(); 331 local_irq_enable();
@@ -342,6 +343,12 @@ int ide_driveid_update(ide_drive_t *drive)
342 ide_dma_off(drive); 343 ide_dma_off(drive);
343 344
344 return 1; 345 return 1;
346out_err:
347 SELECT_MASK(drive, 0);
348 if (rc == 2)
349 printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
350 kfree(id);
351 return 0;
345} 352}
346 353
347int ide_config_drive_speed(ide_drive_t *drive, u8 speed) 354int ide_config_drive_speed(ide_drive_t *drive, u8 speed)