Exemple #1
0
static int proc_ide_read_identify
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
    ide_drive_t	*drive = (ide_drive_t *)data;
    int		len = 0, i = 0;
    int		err = 0;

    len = sprintf(page, "\n");

    if (drive) {
        __le16 *val = (__le16 *)page;

        err = taskfile_lib_get_identify(drive, page);
        if (!err) {
            char *out = (char *)page + SECTOR_SIZE;

            page = out;
            do {
                out += sprintf(out, "%04x%c",
                               le16_to_cpup(val), (++i & 7) ? ' ' : '\n');
                val += 1;
            } while (i < SECTOR_SIZE / 2);
            len = out - page;
        }
    }
    PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
Exemple #2
0
void ide_acpi_port_init_devices(ide_hwif_t *hwif)
{
	ide_drive_t *drive;
	int i, err;

	if (hwif->acpidata == NULL)
		return;

	/*
	 * The ACPI spec mandates that we send information
	 * for both drives, regardless whether they are connected
	 * or not.
	 */
	hwif->drives[0].acpidata = &hwif->acpidata->master;
	hwif->drives[1].acpidata = &hwif->acpidata->slave;

	/*
	 * Send IDENTIFY for each drive
	 */
	for (i = 0; i < MAX_DRIVES; i++) {
		drive = &hwif->drives[i];

		if (!drive->present)
			continue;

		err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
		if (err)
			DEBPRINT("identify device %s failed (%d)\n",
				 drive->name, err);
	}

	if (ide_noacpionboot) {
		DEBPRINT("ACPI methods disabled on boot\n");
		return;
	}

	/* ACPI _PS0 before _STM */
	ide_acpi_set_state(hwif, 1);
	/*
	 * ACPI requires us to call _STM on startup
	 */
	ide_acpi_get_timing(hwif);
	ide_acpi_push_timing(hwif);

	for (i = 0; i < MAX_DRIVES; i++) {
		drive = &hwif->drives[i];

		if (drive->present)
			/* Execute ACPI startup code */
			ide_acpi_exec_tfs(drive);
	}
}
Exemple #3
0
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
{
	/* SATA has no cable restrictions */
	if (HWIF(drive)->sata)
		return 0;
		
	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
	    (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) &&
	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) {
#ifndef CONFIG_IDEDMA_IVB
		if ((drive->id->hw_config & 0x6000) == 0) {
#else /* !CONFIG_IDEDMA_IVB */
		if (((drive->id->hw_config & 0x2000) == 0) ||
		    ((drive->id->hw_config & 0x4000) == 0)) {
#endif /* CONFIG_IDEDMA_IVB */
			printk("%s: Speed warnings UDMA 3/4/5 is not "
				"functional.\n", drive->name);
			return 1;
		}
		if (!HWIF(drive)->udma_four) {
			printk("%s: Speed warnings UDMA 3/4/5 is not "
				"functional.\n",
				HWIF(drive)->name);
			return 1;
		}
	}
	return 0;
}

EXPORT_SYMBOL(ide_ata66_check);

/*
 * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER.
 * 1 : Safe to update drive->id DMA registers.
 * 0 : OOPs not allowed.
 */
int set_transfer (ide_drive_t *drive, ide_task_t *args)
{
	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) &&
	    (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) &&
	    (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) &&
	    (drive->id->dma_ultra ||
	     drive->id->dma_mword ||
	     drive->id->dma_1word))
		return 1;

	return 0;
}

EXPORT_SYMBOL(set_transfer);

u8 ide_auto_reduce_xfer (ide_drive_t *drive)
{
	if (!drive->crc_count)
		return drive->current_speed;
	drive->crc_count = 0;

	switch(drive->current_speed) {
		case XFER_UDMA_7:	return XFER_UDMA_6;
		case XFER_UDMA_6:	return XFER_UDMA_5;
		case XFER_UDMA_5:	return XFER_UDMA_4;
		case XFER_UDMA_4:	return XFER_UDMA_3;
		case XFER_UDMA_3:	return XFER_UDMA_2;
		case XFER_UDMA_2:	return XFER_UDMA_1;
		case XFER_UDMA_1:	return XFER_UDMA_0;
			/*
			 * OOPS we do not goto non Ultra DMA modes
			 * without iCRC's available we force
			 * the system to PIO and make the user
			 * invoke the ATA-1 ATA-2 DMA modes.
			 */
		case XFER_UDMA_0:
		default:		return XFER_PIO_4;
	}
}

EXPORT_SYMBOL(ide_auto_reduce_xfer);

/*
 * Update the 
 */
int ide_driveid_update (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct hd_driveid *id;
#if 0
	id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
	if (!id)
		return 0;

	taskfile_lib_get_identify(drive, (char *)&id);

	ide_fix_driveid(id);
	if (id) {
		drive->id->dma_ultra = id->dma_ultra;
		drive->id->dma_mword = id->dma_mword;
		drive->id->dma_1word = id->dma_1word;
		/* anything more ? */
		kfree(id);
	}
	return 1;
#else
	/*
	 * Re-read drive->id for possible DMA mode
	 * change (copied from ide-probe.c)
	 */
	unsigned long timeout, flags;

	SELECT_MASK(drive, 1);
	if (IDE_CONTROL_REG)
		hwif->OUTB(drive->ctl,IDE_CONTROL_REG);
	ide_delay_50ms();
	hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG);
	timeout = jiffies + WAIT_WORSTCASE;
	do {
		if (time_after(jiffies, timeout)) {
			SELECT_MASK(drive, 0);
			return 0;	/* drive timed-out */
		}
		ide_delay_50ms();	/* give drive a breather */
	} while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT);
	ide_delay_50ms();	/* wait for IRQ and DRQ_STAT */
	if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) {
		SELECT_MASK(drive, 0);
		printk("%s: CHECK for good STATUS\n", drive->name);
		return 0;
	}
	local_irq_save(flags);
	SELECT_MASK(drive, 0);
	id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
	if (!id) {
		local_irq_restore(flags);
		return 0;
	}
	ata_input_data(drive, id, SECTOR_WORDS);
	(void) hwif->INB(IDE_STATUS_REG);	/* clear drive IRQ */
	local_irq_enable();
	local_irq_restore(flags);
	ide_fix_driveid(id);

	drive->id->dma_ultra = id->dma_ultra;
	drive->id->dma_mword = id->dma_mword;
	drive->id->dma_1word = id->dma_1word;
	/* anything more ? */
	kfree(id);

	return 1;
#endif
}
Exemple #4
0
/*
 * Update the 
 */
int ide_driveid_update (ide_drive_t *drive)
{
	ide_hwif_t *hwif	= HWIF(drive);
	struct hd_driveid *id;
#if 0
	id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
	if (!id)
		return 0;

	taskfile_lib_get_identify(drive, (char *)&id);

	ide_fix_driveid(id);
	if (id) {
		drive->id->dma_ultra = id->dma_ultra;
		drive->id->dma_mword = id->dma_mword;
		drive->id->dma_1word = id->dma_1word;
		/* anything more ? */
		kfree(id);
	}
	return 1;
#else
	/*
	 * Re-read drive->id for possible DMA mode
	 * change (copied from ide-probe.c)
	 */
	unsigned long timeout, flags;

	SELECT_MASK(drive, 1);
	if (IDE_CONTROL_REG)
		hwif->OUTB(drive->ctl,IDE_CONTROL_REG);
	msleep(50);
	hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG);
	timeout = jiffies + WAIT_WORSTCASE;
	do {
		if (time_after(jiffies, timeout)) {
			SELECT_MASK(drive, 0);
			return 0;	/* drive timed-out */
		}
		msleep(50);	/* give drive a breather */
	} while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT);
	msleep(50);	/* wait for IRQ and DRQ_STAT */
	if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) {
		SELECT_MASK(drive, 0);
		printk("%s: CHECK for good STATUS\n", drive->name);
		return 0;
	}
	local_irq_save(flags);
	SELECT_MASK(drive, 0);
	id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
	if (!id) {
		local_irq_restore(flags);
		return 0;
	}
	ata_input_data(drive, id, SECTOR_WORDS);
	(void) hwif->INB(IDE_STATUS_REG);	/* clear drive IRQ */
	local_irq_enable();
	local_irq_restore(flags);
	ide_fix_driveid(id);
	if (id) {
		drive->id->dma_ultra = id->dma_ultra;
		drive->id->dma_mword = id->dma_mword;
		drive->id->dma_1word = id->dma_1word;
		/* anything more ? */
		kfree(id);
	}

	return 1;
#endif
}