Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f40c9b0 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

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: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent d45b70ab
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -293,7 +293,12 @@ int ide_driveid_update(ide_drive_t *drive)
	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
	u16 *id;
	unsigned long flags;
	u8 stat;
	int rc;
	u8 uninitialized_var(s);

	id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
	if (id == NULL)
		return 0;

	/*
	 * Re-read drive->id for possible DMA mode
@@ -306,25 +311,21 @@ int ide_driveid_update(ide_drive_t *drive)
	tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);

	if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
		SELECT_MASK(drive, 0);
		return 0;
		rc = 1;
		goto out_err;
	}

	msleep(50);	/* wait for IRQ and ATA_DRQ */
	stat = tp_ops->read_status(hwif);

	if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) {
		SELECT_MASK(drive, 0);
		printk("%s: CHECK for good STATUS\n", drive->name);
		return 0;
	s = tp_ops->read_status(hwif);

	if (!OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
		rc = 2;
		goto out_err;
	}

	local_irq_save(flags);
	SELECT_MASK(drive, 0);
	id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
	if (!id) {
		local_irq_restore(flags);
		return 0;
	}
	tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
	(void)tp_ops->read_status(hwif);	/* clear drive IRQ */
	local_irq_enable();
@@ -342,6 +343,12 @@ int ide_driveid_update(ide_drive_t *drive)
		ide_dma_off(drive);

	return 1;
out_err:
	SELECT_MASK(drive, 0);
	if (rc == 2)
		printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
	kfree(id);
	return 0;
}

int ide_config_drive_speed(ide_drive_t *drive, u8 speed)