Commit ab08629c authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.13 IDE 52

Adapted from patch Bar³omiej ¯o³nierkiewicz:

 - make straight8 a flag in ata_channel instead of byte

 - don't store tables as code in drive_is_flashcard()
   and ide_xfer_verbose()

 - fix init_gendisk() (due to 2.5.13 blksize_size[] change)

 - compress region requesting/releasing
   in channel_probe() and ide_unregister()

 - clean a bit ide_setup_ports()

Start of DMA handling tratment.

 - Fix the parameters to ide_build_dmatable() to be channel and request.
   Rename it to udma_new_table(). udma will mark arch specific functions
   later.

 - Let ide_start_dma() take the request directly as an arguemnt. Rename it to
   ata_start_dma(). After realizing that the usage of the func argument of it
   was bogous and that nobody is using rwproc we where able to remove both of
   them.

 - Fix ide_destroy_dmatable() to take the channel as argument and rename it to
   udma_destroy_table(). This function should have possible architecture
   specific implementation as well at some point in time.

 - Split up the TCQ UDMA handling stuff in to proper functions. Jens must has
   been dreaming as he introduced them ;-).
parent 65ae2979
......@@ -191,7 +191,7 @@ unsigned char IN_BYTE(ide_ioreg_t reg) {
#define ATA_PIO0_STROBE 19
#define ATA_PIO0_HOLD 4
static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq);
static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
void *buffer, unsigned int length);
......@@ -278,7 +278,7 @@ init_e100_ide (void)
hwif->chipset = ide_etrax100;
hwif->tuneproc = &tune_e100_ide;
hwif->dmaproc = &e100_dmaproc;
hwif->udma = &e100_dmaproc;
hwif->ata_read = e100_ide_input_data;
hwif->ata_write = e100_ide_output_data;
hwif->atapi_read = e100_atapi_read;
......@@ -564,13 +564,14 @@ e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
static unsigned int ata_tot_size;
/*
* e100_ide_build_dmatable() prepares a dma request.
* Returns 0 if all went okay, returns 1 otherwise.
* This prepares a dma request. Returns 0 if all went okay, returns 1
* otherwise.
*/
static int e100_ide_build_dmatable (ide_drive_t *drive)
static int e100_udma_new_table(struct ata_channel *ch, struct request *rq)
{
struct request *rq = HWGROUP(drive)->rq;
struct buffer_head *bh = rq->bh;
unsigned long size, addr;
unsigned int count = 0;
......@@ -602,7 +603,7 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
/* did we run out of descriptors? */
if(count >= MAX_DMA_DESCRS) {
printk("%s: too few DMA descriptors\n", drive->name);
printk("%s: too few DMA descriptors\n", ch->name);
return 1;
}
......@@ -623,7 +624,7 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
size > 131072 only one split is necessary */
if(size > 65536) {
/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
ata_descrs[count].sw_len = 0; /* 0 means 65536, this is a 16-bit field */
ata_descrs[count].ctrl = 0;
ata_descrs[count].buf = addr;
......@@ -656,7 +657,7 @@ static int e100_ide_build_dmatable (ide_drive_t *drive)
return 0;
}
printk("%s: empty DMA table?\n", drive->name);
printk("%s: empty DMA table?\n", ch->name);
return 1; /* let the PIO routines handle this weirdness */
}
......@@ -695,7 +696,7 @@ static ide_startstop_t etrax_dma_intr (struct ata_device *drive, struct request
LED_DISK_READ(0);
LED_DISK_WRITE(0);
dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
stat = GET_STAT(); /* get drive status */
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
......@@ -726,7 +727,7 @@ static ide_startstop_t etrax_dma_intr (struct ata_device *drive, struct request
* the caller should revert to PIO for the current request.
*/
static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
static unsigned int reading; /* static to support ide_dma_begin semantics */
int atapi = 0;
......@@ -786,24 +787,21 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
/* set up the Etrax DMA descriptors */
if(e100_ide_build_dmatable (drive))
if(e100_udma_new_table(drive->channel, rq))
return 1;
if(!atapi) {
/* set the irq handler which will finish the request when DMA is done */
ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */
OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
}
/* begin DMA */
*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, start);
/* initiate a multi word dma read using DMA handshaking */
*R_ATA_TRANSFER_CNT =
......@@ -820,7 +818,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
LED_DISK_READ(1);
D(printk("dma read of %d bytes.\n", ata_tot_size));
} else {
/* writing */
......@@ -829,29 +827,25 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
/* set up the Etrax DMA descriptors */
if(e100_ide_build_dmatable (drive))
if(e100_udma_new_table(drive->channel, rq))
return 1;
if(!atapi) {
/* set the irq handler which will finish the request when DMA is done */
ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
/* issue cmd to drive */
OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
}
/* begin DMA */
*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, start);
/* initiate a multi word dma write using DMA handshaking */
*R_ATA_TRANSFER_CNT =
IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
*R_ATA_CTRL_DATA =
IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
IO_STATE(R_ATA_CTRL_DATA, rw, write) |
......@@ -878,7 +872,7 @@ static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
* --- Marcin Dalecki
*/
void ide_release_dma(struct ata_channel *hwif)
void ide_release_dma(struct ata_channel *ch)
{
/* empty */
}
......@@ -10,7 +10,7 @@
O_TARGET := idedriver.o
export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o ataraid.o
export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o ide-dma.o ataraid.o
obj-y :=
obj-m :=
......
......@@ -74,12 +74,12 @@ extern struct ata_timing ata_timing[];
* It's a bit elaborate due to the legacy we have to bear.
*/
extern short ata_timing_mode(ide_drive_t *drive, int map);
extern short ata_timing_mode(struct ata_device *drive, int map);
extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q,
int T, int UT);
extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
struct ata_timing *m, unsigned int what);
extern struct ata_timing* ata_timing_data(short speed);
extern int ata_timing_compute(ide_drive_t *drive,
extern int ata_timing_compute(struct ata_device *drive,
short speed, struct ata_timing *t, int T, int UT);
#endif
......@@ -208,10 +208,10 @@ static byte prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2,
* This routine writes the prepared setup/active/recovery counts
* for a drive into the cmd646 chipset registers to active them.
*/
static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count)
static void program_drive_counts(struct ata_device *drive, int setup_count, int active_count, int recovery_count)
{
unsigned long flags;
ide_drive_t *drives = drive->channel->drives;
struct ata_device *drives = drive->channel->drives;
byte temp_b;
static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
static const byte recovery_counts[] =
......@@ -277,7 +277,7 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
* 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
* Called with 255 at boot time.
*/
static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
{
int recovery_time, clock_time;
byte recovery_count2, cycle_count;
......@@ -351,7 +351,7 @@ static byte cmd680_taskfile_timing(struct ata_channel *hwif)
}
}
static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted)
static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
{
struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev;
......@@ -381,7 +381,7 @@ static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted)
pci_write_config_word(dev, drive_pci, speedt);
}
static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed)
{
byte speed = 0x00;
byte set_pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
......@@ -392,7 +392,7 @@ static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
(void) ide_config_drive_speed(drive, speed);
}
static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed)
static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed)
{
struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev;
......@@ -418,7 +418,7 @@ static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed)
}
}
static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
static void config_chipset_for_pio(struct ata_device *drive, byte set_speed)
{
if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680) {
config_cmd680_chipset_for_pio(drive, set_speed);
......@@ -427,7 +427,7 @@ static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
}
}
static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
struct ata_channel *hwif = drive->channel;
......@@ -496,7 +496,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
return err;
}
static int cmd680_tune_chipset (ide_drive_t *drive, byte speed)
static int cmd680_tune_chipset(struct ata_device *drive, byte speed)
{
struct ata_channel *hwif = drive->channel;
struct pci_dev *dev = hwif->pci_dev;
......@@ -612,7 +612,7 @@ speed_break :
}
#ifdef CONFIG_BLK_DEV_IDEDMA
static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
static int config_cmd64x_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
{
struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
......@@ -697,7 +697,7 @@ static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev,
return rval;
}
static int config_cmd680_chipset_for_dma (ide_drive_t *drive)
static int config_cmd680_chipset_for_dma(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
byte udma_66 = eighty_ninty_three(drive);
......@@ -739,14 +739,14 @@ static int config_cmd680_chipset_for_dma (ide_drive_t *drive)
return rval;
}
static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
static int config_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
{
if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680)
return (config_cmd680_chipset_for_dma(drive));
return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));
}
static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
static int cmd64x_config_drive_for_dma(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
......@@ -839,11 +839,12 @@ static int cmd680_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
byte dma_stat = 0;
byte dma_alt_stat = 0;
byte mask = (drive->channel->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
unsigned long dma_base = drive->channel->dma_base;
struct pci_dev *dev = drive->channel->pci_dev;
struct ata_channel *ch = drive->channel;
u8 dma_stat = 0;
u8 dma_alt_stat = 0;
u8 mask = (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
unsigned long dma_base = ch->dma_base;
struct pci_dev *dev = ch->pci_dev;
byte jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
switch (func) {
......@@ -855,9 +856,9 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
if (jack_slap) {
byte dma_intr = 0;
byte dma_mask = (drive->channel->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
byte dma_reg = (drive->channel->unit) ? ARTTIM2 : CFR;
byte dma_intr = 0;
byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
/*
* DAMN BMIDE is not connected to PCI space!
......@@ -866,7 +867,7 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
*/
(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */
}
ide_destroy_dmatable(drive); /* purge DMA mappings */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
......@@ -891,8 +892,8 @@ static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struc
*/
static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
unsigned long dma_base = hwif->dma_base;
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
byte dma_stat;
switch (func) {
......@@ -903,7 +904,7 @@ static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
dma_stat = inb(dma_base+2); /* get DMA status */
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
ide_destroy_dmatable(drive); /* and free any DMA resources */
udma_destroy_table(ch); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
......@@ -914,48 +915,48 @@ static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
static int cmd680_busproc (ide_drive_t * drive, int state)
static int cmd680_busproc(struct ata_device * drive, int state)
{
#if 0
struct ata_channel *hwif = drive->channel;
u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
struct ata_channel *ch = drive->channel;
u8 addr_mask = (ch->unit) ? 0xB0 : 0xA0;
u32 stat_config = 0;
pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
pci_read_config_dword(ch->pci_dev, addr_mask, &stat_config);
if (!hwif)
if (!ch)
return -EINVAL;
switch (state) {
case BUSSTATE_ON:
hwif->drives[0].failures = 0;
hwif->drives[1].failures = 0;
ch->drives[0].failures = 0;
ch->drives[1].failures = 0;
break;
case BUSSTATE_OFF:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
ch->drives[0].failures = ch->drives[0].max_failures + 1;
ch->drives[1].failures = ch->drives[1].max_failures + 1;
break;
case BUSSTATE_TRISTATE:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
ch->drives[0].failures = ch->drives[0].max_failures + 1;
ch->drives[1].failures = ch->drives[1].max_failures + 1;
break;
default:
return 0;
}
hwif->bus_state = state;
ch->bus_state = state;
#endif
return 0;
}
static void cmd680_reset (ide_drive_t *drive)
static void cmd680_reset(struct ata_device *drive)
{
#if 0
struct ata_channel *hwif = drive->channel;
u8 addr_mask = (hwif->unit) ? 0xB0 : 0xA0;
byte reset = 0;
struct ata_channel *ch = drive->channel;
u8 addr_mask = (ch->unit) ? 0xB0 : 0xA0;
u8 reset = 0;
pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03);
pci_read_config_byte(ch->pci_dev, addr_mask, &reset);
pci_write_config_byte(ch->pci_dev, addr_mask, reset|0x03);
#endif
}
......
......@@ -312,10 +312,10 @@ static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
* by HighPoint|Triones Technologies, Inc.
*/
int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
unsigned long dma_base = hwif->dma_base;
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
unsigned int count, reading = 0;
byte dma_stat;
......@@ -325,9 +325,9 @@ int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct requ
case ide_dma_read:
reading = 1 << 3;
case ide_dma_write:
if (!(count = ide_build_dmatable(drive, func)))
if (!(count = udma_new_table(ch, rq)))
return 1; /* try PIO instead of DMA */
outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
reading |= 0x01;
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
......@@ -342,7 +342,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct requ
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
ide_destroy_dmatable(drive); /* purge DMA mappings */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
......
......@@ -242,9 +242,9 @@ static int ide_build_sglist(struct ata_channel *hwif, struct request *rq)
}
static int
icside_build_dmatable(ide_drive_t *drive, int reading)
icside_udma_new_table(struct ata_channel *ch, struct request *rq)
{
return drive->channel->sg_nents = ide_build_sglist(drive->channel, HWGROUP(drive)->rq);
return ch->sg_nents = ide_build_sglist(ch, rq);
}
/* Teardown mappings after DMA has completed. */
......@@ -332,7 +332,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *
int i;
byte stat, dma_stat;
dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
stat = GET_STAT(); /* get drive status */
if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
if (!dma_stat) {
......@@ -350,7 +350,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *
static int
icside_dma_check(ide_drive_t *drive)
icside_dma_check(struct ata_device *drive, struct request *rq)
{
struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
......@@ -381,14 +381,7 @@ icside_dma_check(ide_drive_t *drive)
out:
func = icside_config_if(drive, xfer_mode);
return hwif->dmaproc(func, drive);
}
static int
icside_dma_verbose(ide_drive_t *drive)
{
printk(", DMA");
return 1;
return hwif->udma(func, drive, rq);
}
static int
......@@ -413,12 +406,12 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
return 0;
case ide_dma_check:
return icside_dma_check(drive);
return icside_dma_check(drive, rq);
case ide_dma_read:
reading = 1;
case ide_dma_write:
count = icside_build_dmatable(drive, reading);
count = icside_udma_new_table(hwif, rq);
if (!count)
return 1;
disable_dma(hwif->hw.dma);
......@@ -458,9 +451,6 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_test_irq:
return inb((unsigned long)hwif->hw.priv) & 1;
case ide_dma_verbose:
return icside_dma_verbose(drive);
case ide_dma_timeout:
default:
printk("icside_dmaproc: unsupported function: %d\n", func);
......
......@@ -2652,7 +2652,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
udma_print(drive);
#endif
printk("\n");
......
......@@ -89,7 +89,7 @@ static int lba_capacity_is_ok(struct hd_driveid *id)
return 0; /* lba_capacity value may be bad */
}
static u8 get_command(ide_drive_t *drive, int cmd)
static u8 get_command(struct ata_device *drive, int cmd)
{
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
......@@ -345,7 +345,7 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
return chs_do_request(drive, rq, block);
}
static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
static int idedisk_open (struct inode *inode, struct file *filp, struct ata_device *drive)
{
MOD_INC_USE_COUNT;
if (drive->removable && drive->usage == 1) {
......@@ -370,7 +370,7 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
return 0;
}
static int idedisk_flushcache(ide_drive_t *drive)
static int idedisk_flushcache(struct ata_device *drive)
{
struct ata_taskfile args;
......@@ -386,7 +386,7 @@ static int idedisk_flushcache(ide_drive_t *drive)
return ide_raw_taskfile(drive, &args, NULL);
}
static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
static void idedisk_release (struct inode *inode, struct file *filp, struct ata_device *drive)
{
if (drive->removable && !drive->usage) {
struct ata_taskfile args;
......@@ -408,7 +408,7 @@ static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t
MOD_DEC_USE_COUNT;
}
static int idedisk_check_media_change (ide_drive_t *drive)
static int idedisk_check_media_change(struct ata_device *drive)
{
/* if removable, always assume it was changed */
return drive->removable;
......@@ -474,7 +474,7 @@ static ide_startstop_t idedisk_special(struct ata_device *drive)
return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
}
static void idedisk_pre_reset (ide_drive_t *drive)
static void idedisk_pre_reset(struct ata_device *drive)
{
int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
......@@ -490,7 +490,7 @@ static void idedisk_pre_reset (ide_drive_t *drive)
#ifdef CONFIG_PROC_FS
static int smart_enable(ide_drive_t *drive)
static int smart_enable(struct ata_device *drive)
{
struct ata_taskfile args;
......@@ -504,7 +504,7 @@ static int smart_enable(ide_drive_t *drive)
return ide_raw_taskfile(drive, &args, NULL);
}
static int get_smart_values(ide_drive_t *drive, u8 *buf)
static int get_smart_values(struct ata_device *drive, u8 *buf)
{
struct ata_taskfile args;
......@@ -521,7 +521,7 @@ static int get_smart_values(ide_drive_t *drive, u8 *buf)
return ide_raw_taskfile(drive, &args, buf);
}
static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
static int get_smart_thresholds(struct ata_device *drive, u8 *buf)
{
struct ata_taskfile args;
......@@ -541,7 +541,7 @@ static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
static int proc_idedisk_read_cache
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
struct ata_device *drive = (struct ata_device *) data;
char *out = page;
int len;
......@@ -555,7 +555,7 @@ static int proc_idedisk_read_cache
static int proc_idedisk_read_smart_thresholds
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *)data;
struct ata_device *drive = (struct ata_device *)data;
int len = 0, i = 0;
if (!get_smart_thresholds(drive, page)) {
......@@ -574,8 +574,8 @@ static int proc_idedisk_read_smart_thresholds
static int proc_idedisk_read_smart_values
(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;
struct ata_device *drive = (struct ata_device *)data;
int len = 0, i = 0;
if (!get_smart_values(drive, page)) {
unsigned short *val = (unsigned short *) page;
......@@ -594,7 +594,7 @@ static int proc_idedisk_read_smart_values
static int proc_idedisk_read_tcq
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = (ide_drive_t *) data;
struct ata_device *drive = (struct ata_device *) data;
char *out = page;
int len, cmds, i;
unsigned long flags;
......@@ -658,7 +658,7 @@ static ide_proc_entry_t idedisk_proc[] = {
* This is tightly woven into the driver->special can not touch.
* DON'T do it again until a total personality rewrite is committed.
*/
static int set_multcount(ide_drive_t *drive, int arg)
static int set_multcount(struct ata_device *drive, int arg)
{
struct request rq;
......@@ -670,12 +670,12 @@ static int set_multcount(ide_drive_t *drive, int arg)
drive->mult_req = arg;
drive->special_cmd |= ATA_SPECIAL_MMODE;
ide_do_drive_cmd (drive, &rq, ide_wait);
ide_do_drive_cmd(drive, &rq, ide_wait);
return (drive->mult_count == arg) ? 0 : -EIO;
}
static int set_nowerr(ide_drive_t *drive, int arg)
static int set_nowerr(struct ata_device *drive, int arg)
{
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
......@@ -686,7 +686,7 @@ static int set_nowerr(ide_drive_t *drive, int arg)
return 0;
}
static int write_cache(ide_drive_t *drive, int arg)
static int write_cache(struct ata_device *drive, int arg)
{
struct ata_taskfile args;
......@@ -704,7 +704,7 @@ static int write_cache(ide_drive_t *drive, int arg)
return 0;
}
static int idedisk_standby(ide_drive_t *drive)
static int idedisk_standby(struct ata_device *drive)
{
struct ata_taskfile args;
......@@ -715,7 +715,7 @@ static int idedisk_standby(ide_drive_t *drive)
return ide_raw_taskfile(drive, &args, NULL);
}
static int set_acoustic(ide_drive_t *drive, int arg)
static int set_acoustic(struct ata_device *drive, int arg)
{
struct ata_taskfile args;
......@@ -732,7 +732,7 @@ static int set_acoustic(ide_drive_t *drive, int arg)
}
#ifdef CONFIG_BLK_DEV_IDE_TCQ
static int set_using_tcq(ide_drive_t *drive, int arg)
static int set_using_tcq(struct ata_device *drive, int arg)
{
if (!drive->driver)
return -EPERM;
......@@ -750,14 +750,14 @@ static int set_using_tcq(ide_drive_t *drive, int arg)
drive->queue_depth = drive->id->queue_depth + 1;
}
if (drive->channel->udma(arg ? ide_dma_queued_on : ide_dma_queued_off, drive, NULL))
if (udma_tcq_enable(drive, arg))
return -EIO;
return 0;
}
#endif
static int probe_lba_addressing (ide_drive_t *drive, int arg)
static int probe_lba_addressing(struct ata_device *drive, int arg)
{
drive->addressing = 0;
......@@ -768,12 +768,12 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg)
return 0;
}
static int set_lba_addressing (ide_drive_t *drive, int arg)
static int set_lba_addressing(struct ata_device *drive, int arg)
{
return (probe_lba_addressing(drive, arg));
}
static void idedisk_add_settings(ide_drive_t *drive)
static void idedisk_add_settings(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
......@@ -795,7 +795,7 @@ static void idedisk_add_settings(ide_drive_t *drive)
static int idedisk_suspend(struct device *dev, u32 state, u32 level)
{
ide_drive_t *drive = dev->driver_data;
struct ata_device *drive = dev->driver_data;
/* I hope that every freeze operations from the upper levels have
* already been done...
......@@ -822,7 +822,7 @@ static int idedisk_suspend(struct device *dev, u32 state, u32 level)
static int idedisk_resume(struct device *dev, u32 level)
{
ide_drive_t *drive = dev->driver_data;
struct ata_device *drive = dev->driver_data;
if (level != RESUME_RESTORE_STATE)
return 0;
......@@ -916,7 +916,7 @@ static u64 native_max_address_ext(struct ata_device *drive)
* Sets maximum virtual LBA address of the drive.
* Returns new maximum virtual LBA address (> 0) or 0 on failure.
*/
static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
{
struct ata_taskfile args;
sector_t addr_set = 0;
......@@ -945,7 +945,7 @@ static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
return addr_set;
}
static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
{
struct ata_taskfile args;
u64 addr_set = 0;
......@@ -1177,7 +1177,7 @@ static void idedisk_setup(struct ata_device *drive)
drive->bios_cyl, drive->bios_head, drive->bios_sect);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
udma_print(drive);
#endif
printk("\n");
......@@ -1213,7 +1213,7 @@ static void idedisk_setup(struct ata_device *drive)
probe_lba_addressing(drive, 1);
}
static int idedisk_cleanup(ide_drive_t *drive)
static int idedisk_cleanup(struct ata_device *drive)
{
if (!drive)
return 0;
......@@ -1250,7 +1250,7 @@ MODULE_DESCRIPTION("ATA DISK Driver");
static void __exit idedisk_exit (void)
{
ide_drive_t *drive;
struct ata_device *drive;
int failed = 0;
while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", &idedisk_driver, failed)) != NULL) {
......@@ -1267,9 +1267,9 @@ static void __exit idedisk_exit (void)
}
}
int idedisk_init (void)
int idedisk_init(void)
{
ide_drive_t *drive;
struct ata_device *drive;
int failed = 0;
MOD_INC_USE_COUNT;
......
/*
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (c) 1995-1998 Mark Lord
*
......@@ -63,12 +64,12 @@
*
* And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
*
* check_drive_lists(ide_drive_t *drive, int good_bad)
*
* ATA-66/100 and recovery functions, I forgot the rest......
*/
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/timer.h>
......@@ -192,11 +193,11 @@ const char *bad_dma_drives[] = {"WDC AC11000H",
#endif
/*
* dma_intr() is the handler for disk read/write DMA interrupts
* This is the handler for disk read/write DMA interrupts.
*/
ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
{
byte stat, dma_stat;
u8 stat, dma_stat;
dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
if (OK_STAT(stat = GET_STAT(),DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
......@@ -204,7 +205,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
__ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped;
}
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
}
return ide_error(drive, "dma_intr", stat);
......@@ -269,107 +270,12 @@ static int build_sglist(struct ata_channel *ch, struct request *rq)
return pci_map_sg(ch->pci_dev, sg, nents, ch->sg_dma_direction);
}
/*
* This prepares a dma request. Returns 0 if all went okay, returns 1
* otherwise. May also be invoked from trm290.c
*/
int ide_build_dmatable(struct ata_device *drive, ide_dma_action_t func)
{
struct ata_channel *ch = drive->channel;
unsigned int *table = ch->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
#else
const int is_trm290_chipset = 0;
#endif
unsigned int count = 0;
int i;
struct scatterlist *sg;
ch->sg_nents = i = build_sglist(ch, HWGROUP(drive)->rq);
if (!i)
return 0;
sg = ch->sg_table;
while (i) {
u32 cur_addr;
u32 cur_len;
cur_addr = sg_dma_address(sg);
cur_len = sg_dma_len(sg);
/*
* Fill in the dma table, without crossing any 64kB boundaries.
* Most hardware requires 16-bit alignment of all blocks,
* but the trm290 requires 32-bit alignment.
*/
while (cur_len) {
u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
if (count++ >= PRD_ENTRIES) {
printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
count, ch->sg_nents, cur_len, cur_addr);
BUG();
}
if (bcount > cur_len)
bcount = cur_len;
*table++ = cpu_to_le32(cur_addr);
xcount = bcount & 0xffff;
if (is_trm290_chipset)
xcount = ((xcount >> 2) - 1) << 16;
if (xcount == 0x0000) {
/*
* Most chipsets correctly interpret a length of
* 0x0000 as 64KB, but at least one (e.g. CS5530)
* misinterprets it as zero (!). So here we break
* the 64KB entry into two 32KB entries instead.
*/
if (count++ >= PRD_ENTRIES) {
pci_unmap_sg(ch->pci_dev, sg,
ch->sg_nents,
ch->sg_dma_direction);
return 0;
}
*table++ = cpu_to_le32(0x8000);
*table++ = cpu_to_le32(cur_addr + 0x8000);
xcount = 0x8000;
}
*table++ = cpu_to_le32(xcount);
cur_addr += bcount;
cur_len -= bcount;
}
sg++;
i--;
}
if (!count)
printk("%s: empty DMA table?\n", drive->name);
else if (!is_trm290_chipset)
*--table |= cpu_to_le32(0x80000000);
return count;
}
/* Teardown mappings after DMA has completed. */
void ide_destroy_dmatable (ide_drive_t *drive)
{
struct pci_dev *dev = drive->channel->pci_dev;
struct scatterlist *sg = drive->channel->sg_table;
int nents = drive->channel->sg_nents;
pci_unmap_sg(dev, sg, nents, drive->channel->sg_dma_direction);
}
/*
* For both Blacklisted and Whitelisted drives.
* This is setup to be called as an extern for future support
* to other special driver code.
*/
int check_drive_lists (ide_drive_t *drive, int good_bad)
int check_drive_lists(struct ata_device *drive, int good_bad)
{
struct hd_driveid *id = drive->id;
......@@ -407,80 +313,43 @@ int check_drive_lists (ide_drive_t *drive, int good_bad)
return 0;
}
int report_drive_dmaing (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
if ((id->dma_ultra >> 15) & 1) {
printk(", UDMA(mode 7)"); /* UDMA BIOS-enabled! */
} else {
printk(", UDMA(133)"); /* UDMA BIOS-enabled! */
}
} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
if ((id->dma_ultra >> 13) & 1) {
printk(", UDMA(100)"); /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 12) & 1) {
printk(", UDMA(66)"); /* UDMA BIOS-enabled! */
} else {
printk(", UDMA(44)"); /* UDMA BIOS-enabled! */
}
} else if ((id->field_valid & 4) &&
(id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
if ((id->dma_ultra >> 10) & 1) {
printk(", UDMA(33)"); /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 9) & 1) {
printk(", UDMA(25)"); /* UDMA BIOS-enabled! */
} else {
printk(", UDMA(16)"); /* UDMA BIOS-enabled! */
}
} else if (id->field_valid & 4) {
printk(", (U)DMA"); /* Can be BIOS-enabled! */
} else {
printk(", DMA");
}
return 1;
}
static int config_drive_for_dma (ide_drive_t *drive)
static int config_drive_for_dma(struct ata_device *drive)
{
int config_allows_dma = 1;
struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
struct ata_channel *ch = drive->channel;
#ifdef CONFIG_IDEDMA_ONLYDISK
if (drive->type != ATA_DISK)
config_allows_dma = 0;
#endif
if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) {
if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive, NULL))
return hwif->udma(ide_dma_off, drive, NULL);
return ch->udma(ide_dma_off, drive, NULL);
/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
if ((id->dma_ultra & (id->dma_ultra >> 14) & 2))
return hwif->udma(ide_dma_on, drive, NULL);
return ch->udma(ide_dma_on, drive, NULL);
/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
return hwif->udma(ide_dma_on, drive, NULL);
return ch->udma(ide_dma_on, drive, NULL);
/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
if (id->field_valid & 4) /* UltraDMA */
if ((id->dma_ultra & (id->dma_ultra >> 8) & 7))
return hwif->udma(ide_dma_on, drive, NULL);
return ch->udma(ide_dma_on, drive, NULL);
/* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */
if (id->field_valid & 2) /* regular DMA */
if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
return hwif->udma(ide_dma_on, drive, NULL);
return ch->udma(ide_dma_on, drive, NULL);
/* Consult the list of known "good" drives */
if (ide_dmaproc(ide_dma_good_drive, drive, NULL))
return hwif->udma(ide_dma_on, drive, NULL);
return ch->udma(ide_dma_on, drive, NULL);
}
return hwif->udma(ide_dma_off_quietly, drive, NULL);
return ch->udma(ide_dma_off_quietly, drive, NULL);
}
/*
......@@ -508,7 +377,7 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *__rq)
return 0;
}
static void ide_toggle_bounce(ide_drive_t *drive, int on)
static void ide_toggle_bounce(struct ata_device *drive, int on)
{
u64 addr = BLK_BOUNCE_HIGH;
......@@ -522,26 +391,20 @@ static void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(&drive->queue, addr);
}
int ide_start_dma(ide_dma_action_t func, struct ata_device *drive)
int ata_start_dma(struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
unsigned long dma_base = hwif->dma_base;
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
unsigned int reading = 0;
if (rq_data_dir(HWGROUP(drive)->rq) == READ)
if (rq_data_dir(rq) == READ)
reading = 1 << 3;
/* active tuning based on IO direction */
if (hwif->rwproc)
hwif->rwproc(drive, func);
/*
* try PIO instead of DMA
*/
if (!ide_build_dmatable(drive, func))
/* try PIO instead of DMA */
if (!udma_new_table(ch, rq))
return 1;
outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
outb(reading, dma_base); /* specify r/w */
outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
drive->waiting_for_dma = 1;
......@@ -566,11 +429,11 @@ int ide_start_dma(ide_dma_action_t func, struct ata_device *drive)
*/
int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
unsigned long dma_base = hwif->dma_base;
byte unit = (drive->select.b.unit & 0x01);
struct ata_channel *ch = drive->channel;
unsigned long dma_base = ch->dma_base;
u8 unit = (drive->select.b.unit & 0x01);
unsigned int reading = 0, set_high = 1;
byte dma_stat;
u8 dma_stat;
switch (func) {
case ide_dma_off:
......@@ -579,7 +442,7 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
set_high = 0;
outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
hwif->udma(ide_dma_queued_off, drive, rq);
udma_tcq_enable(drive, 0);
#endif
case ide_dma_on:
ide_toggle_bounce(drive, set_high);
......@@ -587,7 +450,7 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
if (drive->using_dma) {
outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
hwif->udma(ide_dma_queued_on, drive, rq);
udma_tcq_enable(drive, 1);
#endif
}
return 0;
......@@ -596,7 +459,7 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
case ide_dma_read:
reading = 1 << 3;
case ide_dma_write:
if (ide_start_dma(func, drive))
if (ata_start_dma(drive, rq))
return 1;
if (drive->type != ATA_DISK)
......@@ -613,14 +476,6 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
}
return drive->channel->udma(ide_dma_begin, drive, NULL);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
case ide_dma_queued_on:
case ide_dma_queued_off:
case ide_dma_read_queued:
case ide_dma_write_queued:
case ide_dma_queued_start:
return ide_tcq_dmaproc(func, drive, rq);
#endif
case ide_dma_begin:
/* Note that this is done *after* the cmd has
* been issued to the drive, as per the BM-IDE spec.
......@@ -634,13 +489,13 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
ide_destroy_dmatable(drive); /* purge DMA mappings */
udma_destroy_table(ch); /* purge DMA mappings */
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
#if 0 /* do not set unless you know what you are doing */
if (dma_stat & 4) {
byte stat = GET_STAT();
u8 stat = GET_STAT();
outb(dma_base+2, dma_stat & 0xE4);
}
#endif
......@@ -648,8 +503,6 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
case ide_dma_bad_drive:
case ide_dma_good_drive:
return check_drive_lists(drive, (func == ide_dma_good_drive));
case ide_dma_verbose:
return report_drive_dmaing(drive);
case ide_dma_timeout:
printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
return 1;
......@@ -666,61 +519,61 @@ int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request
/*
* Needed for allowing full modular support of ide-driver
*/
void ide_release_dma(struct ata_channel *hwif)
void ide_release_dma(struct ata_channel *ch)
{
if (!hwif->dma_base)
if (!ch->dma_base)
return;
if (hwif->dmatable_cpu) {
pci_free_consistent(hwif->pci_dev,
if (ch->dmatable_cpu) {
pci_free_consistent(ch->pci_dev,
PRD_ENTRIES * PRD_BYTES,
hwif->dmatable_cpu,
hwif->dmatable_dma);
hwif->dmatable_cpu = NULL;
ch->dmatable_cpu,
ch->dmatable_dma);
ch->dmatable_cpu = NULL;
}
if (hwif->sg_table) {
kfree(hwif->sg_table);
hwif->sg_table = NULL;
if (ch->sg_table) {
kfree(ch->sg_table);
ch->sg_table = NULL;
}
if ((hwif->dma_extra) && (hwif->unit == 0))
release_region((hwif->dma_base + 16), hwif->dma_extra);
release_region(hwif->dma_base, 8);
hwif->dma_base = 0;
if ((ch->dma_extra) && (ch->unit == 0))
release_region((ch->dma_base + 16), ch->dma_extra);
release_region(ch->dma_base, 8);
ch->dma_base = 0;
}
/*
* This can be called for a dynamically installed interface. Don't __init it
*/
void ide_setup_dma(struct ata_channel *hwif, unsigned long dma_base, unsigned int num_ports)
void ide_setup_dma(struct ata_channel *ch, unsigned long dma_base, unsigned int num_ports)
{
printk(" %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
printk(" %s: BM-DMA at 0x%04lx-0x%04lx", ch->name, dma_base, dma_base + num_ports - 1);
if (check_region(dma_base, num_ports)) {
printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n");
return;
}
request_region(dma_base, num_ports, hwif->name);
hwif->dma_base = dma_base;
hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
request_region(dma_base, num_ports, ch->name);
ch->dma_base = dma_base;
ch->dmatable_cpu = pci_alloc_consistent(ch->pci_dev,
PRD_ENTRIES * PRD_BYTES,
&hwif->dmatable_dma);
if (hwif->dmatable_cpu == NULL)
&ch->dmatable_dma);
if (ch->dmatable_cpu == NULL)
goto dma_alloc_failure;
hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
ch->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
GFP_KERNEL);
if (hwif->sg_table == NULL) {
pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES,
hwif->dmatable_cpu, hwif->dmatable_dma);
if (ch->sg_table == NULL) {
pci_free_consistent(ch->pci_dev, PRD_ENTRIES * PRD_BYTES,
ch->dmatable_cpu, ch->dmatable_dma);
goto dma_alloc_failure;
}
hwif->udma = ide_dmaproc;
ch->udma = ide_dmaproc;
if (hwif->chipset != ide_trm290) {
byte dma_stat = inb(dma_base+2);
if (ch->chipset != ide_trm290) {
u8 dma_stat = inb(dma_base+2);
printk(", BIOS settings: %s:%s, %s:%s",
hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
ch->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
ch->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
}
printk("\n");
return;
......@@ -728,3 +581,141 @@ void ide_setup_dma(struct ata_channel *hwif, unsigned long dma_base, unsigned in
dma_alloc_failure:
printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
}
/****************************************************************************
* UDMA function which should have architecture specific counterparts where
* neccessary.
*/
/*
* This prepares a dma request. Returns 0 if all went okay, returns 1
* otherwise. May also be invoked from trm290.c
*/
int udma_new_table(struct ata_channel *ch, struct request *rq)
{
unsigned int *table = ch->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
#else
const int is_trm290_chipset = 0;
#endif
unsigned int count = 0;
int i;
struct scatterlist *sg;
ch->sg_nents = i = build_sglist(ch, rq);
if (!i)
return 0;
sg = ch->sg_table;
while (i) {
u32 cur_addr;
u32 cur_len;
cur_addr = sg_dma_address(sg);
cur_len = sg_dma_len(sg);
/*
* Fill in the dma table, without crossing any 64kB boundaries.
* Most hardware requires 16-bit alignment of all blocks,
* but the trm290 requires 32-bit alignment.
*/
while (cur_len) {
u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
if (count++ >= PRD_ENTRIES) {
printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
count, ch->sg_nents, cur_len, cur_addr);
BUG();
}
if (bcount > cur_len)
bcount = cur_len;
*table++ = cpu_to_le32(cur_addr);
xcount = bcount & 0xffff;
if (is_trm290_chipset)
xcount = ((xcount >> 2) - 1) << 16;
if (xcount == 0x0000) {
/*
* Most chipsets correctly interpret a length of
* 0x0000 as 64KB, but at least one (e.g. CS5530)
* misinterprets it as zero (!). So here we break
* the 64KB entry into two 32KB entries instead.
*/
if (count++ >= PRD_ENTRIES) {
pci_unmap_sg(ch->pci_dev, sg,
ch->sg_nents,
ch->sg_dma_direction);
return 0;
}
*table++ = cpu_to_le32(0x8000);
*table++ = cpu_to_le32(cur_addr + 0x8000);
xcount = 0x8000;
}
*table++ = cpu_to_le32(xcount);
cur_addr += bcount;
cur_len -= bcount;
}
sg++;
i--;
}
if (!count)
printk(KERN_ERR "%s: empty DMA table?\n", ch->name);
else if (!is_trm290_chipset)
*--table |= cpu_to_le32(0x80000000);
return count;
}
/* Teardown mappings after DMA has completed. */
void udma_destroy_table(struct ata_channel *ch)
{
pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction);
}
void udma_print(struct ata_device *drive)
{
#ifdef CONFIG_ARCH_ACORN
printk(", DMA");
#else
struct hd_driveid *id = drive->id;
char *str = NULL;
if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
if ((id->dma_ultra >> 15) & 1)
str = ", UDMA(mode 7)"; /* UDMA BIOS-enabled! */
else
str = ", UDMA(133)"; /* UDMA BIOS-enabled! */
} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
if ((id->dma_ultra >> 13) & 1) {
str = ", UDMA(100)"; /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 12) & 1) {
str = ", UDMA(66)"; /* UDMA BIOS-enabled! */
} else {
str = ", UDMA(44)"; /* UDMA BIOS-enabled! */
}
} else if ((id->field_valid & 4) &&
(id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
if ((id->dma_ultra >> 10) & 1) {
str = ", UDMA(33)"; /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 9) & 1) {
str = ", UDMA(25)"; /* UDMA BIOS-enabled! */
} else {
str = ", UDMA(16)"; /* UDMA BIOS-enabled! */
}
} else if (id->field_valid & 4)
str = ", (U)DMA"; /* Can be BIOS-enabled! */
else
str = ", DMA";
printk(str);
#endif
}
EXPORT_SYMBOL(udma_print);
......@@ -44,29 +44,38 @@
*/
char *ide_xfer_verbose (byte xfer_rate)
{
switch(xfer_rate) {
case XFER_UDMA_7: return("UDMA 7");
case XFER_UDMA_6: return("UDMA 6");
case XFER_UDMA_5: return("UDMA 5");
case XFER_UDMA_4: return("UDMA 4");
case XFER_UDMA_3: return("UDMA 3");
case XFER_UDMA_2: return("UDMA 2");
case XFER_UDMA_1: return("UDMA 1");
case XFER_UDMA_0: return("UDMA 0");
case XFER_MW_DMA_2: return("MW DMA 2");
case XFER_MW_DMA_1: return("MW DMA 1");
case XFER_MW_DMA_0: return("MW DMA 0");
case XFER_SW_DMA_2: return("SW DMA 2");
case XFER_SW_DMA_1: return("SW DMA 1");
case XFER_SW_DMA_0: return("SW DMA 0");
case XFER_PIO_4: return("PIO 4");
case XFER_PIO_3: return("PIO 3");
case XFER_PIO_2: return("PIO 2");
case XFER_PIO_1: return("PIO 1");
case XFER_PIO_0: return("PIO 0");
case XFER_PIO_SLOW: return("PIO SLOW");
default: return("XFER ERROR");
}
static struct ide_xfer_par {
byte rate;
char *name;
} xfer_verbose[] = {
{ XFER_UDMA_7, "UDMA 7" },
{ XFER_UDMA_6, "UDMA 6" },
{ XFER_UDMA_5, "UDMA 5" },
{ XFER_UDMA_4, "UDMA 4" },
{ XFER_UDMA_3, "UDMA 3" },
{ XFER_UDMA_2, "UDMA 2" },
{ XFER_UDMA_1, "UDMA 1" },
{ XFER_UDMA_0, "UDMA 0" },
{ XFER_MW_DMA_2, "MW DMA 2" },
{ XFER_MW_DMA_1, "MW DMA 1" },
{ XFER_MW_DMA_0, "MW DMA 0" },
{ XFER_SW_DMA_2, "SW DMA 2" },
{ XFER_SW_DMA_1, "SW DMA 1" },
{ XFER_SW_DMA_0, "SW DMA 0" },
{ XFER_PIO_4, "PIO 4" },
{ XFER_PIO_3, "PIO 3" },
{ XFER_PIO_2, "PIO 2" },
{ XFER_PIO_1, "PIO 1" },
{ XFER_PIO_0, "PIO 0" },
{ XFER_PIO_SLOW, "PIO SLOW" },
};
int i = 0;
for (; i < ARRAY_SIZE(xfer_verbose); i++)
if (xfer_verbose[i].rate == xfer_rate)
return xfer_verbose[i].name;
return "XFER ERROR";
}
byte ide_auto_reduce_xfer (ide_drive_t *drive)
......
......@@ -1164,9 +1164,9 @@ pmac_ide_build_dmatable(struct ata_device *drive, struct request *rq, int ix, in
/* Teardown mappings after DMA has completed. */
static void
pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
pmac_ide_destroy_dmatable(struct ata_channel *ch, int ix)
{
struct pci_dev *dev = drive->channel->pci_dev;
struct pci_dev *dev = ch->pci_dev;
struct scatterlist *sg = pmac_ide[ix].sg_table;
int nents = pmac_ide[ix].sg_nents;
......@@ -1367,10 +1367,6 @@ static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
break;
case ide_dma_read:
case ide_dma_write:
/* this almost certainly isn't needed since we don't
appear to have a rwproc */
if (drive->channel->rwproc)
drive->channel->rwproc(drive, func);
reading = (func == ide_dma_read);
if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
return 1;
......@@ -1404,7 +1400,7 @@ static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
drive->waiting_for_dma = 0;
dstat = in_le32(&dma->status);
out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
pmac_ide_destroy_dmatable(drive, ix);
pmac_ide_destroy_dmatable(drive->channel, ix);
/* verify good dma status */
return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
......@@ -1453,8 +1449,6 @@ static int pmac_ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, str
case ide_dma_bad_drive:
case ide_dma_good_drive:
return check_drive_lists(drive, (func == ide_dma_good_drive));
case ide_dma_verbose:
return report_drive_dmaing(drive);
case ide_dma_retune:
case ide_dma_lostirq:
case ide_dma_timeout:
......
......@@ -448,7 +448,7 @@ static inline void probe_for_drive(struct ata_device *drive)
*/
static void channel_probe(struct ata_channel *ch)
{
unsigned int unit;
unsigned int i;
unsigned long flags;
int error;
......@@ -463,8 +463,8 @@ static void channel_probe(struct ata_channel *ch)
/*
* Check for the presence of a channel by probing for drives on it.
*/
for (unit = 0; unit < MAX_DRIVES; ++unit) {
struct ata_device *drive = &ch->drives[unit];
for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[i];
probe_for_drive(drive);
......@@ -483,23 +483,8 @@ static void channel_probe(struct ata_channel *ch)
error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 8, ch->name);
ch->straight8 = 1;
} else {
if (ch->io_ports[IDE_DATA_OFFSET])
error += !request_region(ch->io_ports[IDE_DATA_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_ERROR_OFFSET])
error += !request_region(ch->io_ports[IDE_ERROR_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_NSECTOR_OFFSET])
error += !request_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_SECTOR_OFFSET])
error += !request_region(ch->io_ports[IDE_SECTOR_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_LCYL_OFFSET])
error += !request_region(ch->io_ports[IDE_LCYL_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_HCYL_OFFSET])
error += !request_region(ch->io_ports[IDE_HCYL_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_SELECT_OFFSET])
error += !request_region(ch->io_ports[IDE_SELECT_OFFSET], 1, ch->name);
if (ch->io_ports[IDE_STATUS_OFFSET])
error += !request_region(ch->io_ports[IDE_STATUS_OFFSET], 1, ch->name);
for (i = 0; i < 8; i++)
error += !request_region(ch->io_ports[i], 1, ch->name);
}
if (ch->io_ports[IDE_CONTROL_OFFSET])
error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
......@@ -561,8 +546,8 @@ static void channel_probe(struct ata_channel *ch)
/*
* Now setup the PIO transfer modes of the drives on this channel.
*/
for (unit = 0; unit < MAX_DRIVES; ++unit) {
struct ata_device *drive = &ch->drives[unit];
for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[i];
if (drive->present && (drive->autotune == 1)) {
if (drive->channel->tuneproc)
......@@ -819,6 +804,16 @@ static void channel_init(struct ata_channel *ch)
goto err_kmalloc_gd_part;
memset(gd->part, 0, ATA_MINORS * sizeof(struct hd_struct));
gd->de_arr = kmalloc (sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
if (!gd->de_arr)
goto err_kmalloc_gd_de_arr;
memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
gd->flags = kmalloc (sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
if (!gd->flags)
goto err_kmalloc_gd_flags;
memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
for (unit = 0; unit < MAX_DRIVES; ++unit)
ch->drives[unit].part = &gd->part[unit << PARTN_BITS];
......
......@@ -130,12 +130,12 @@ static void ata_write_slow(struct ata_device *drive, void *buffer, unsigned int
}
#endif
static void ata_read_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
static void ata_read_16(struct ata_device *drive, void *buffer, unsigned int wcount)
{
insw(IDE_DATA_REG, buffer, wcount<<1);
}
static void ata_write_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
static void ata_write_16(struct ata_device *drive, void *buffer, unsigned int wcount)
{
outsw(IDE_DATA_REG, buffer, wcount<<1);
}
......@@ -143,7 +143,7 @@ static void ata_write_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
/*
* This is used for most PIO data transfers *from* the device.
*/
void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
void ata_read(struct ata_device *drive, void *buffer, unsigned int wcount)
{
int io_32bit;
......@@ -178,7 +178,7 @@ void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
/*
* This is used for most PIO data transfers *to* the device interface.
*/
void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
{
int io_32bit;
......@@ -213,7 +213,7 @@ void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
* so if an odd bytecount is specified, be sure that there's at least one
* extra byte allocated for the buffer.
*/
void atapi_read(ide_drive_t *drive, void *buffer, unsigned int bytecount)
void atapi_read(struct ata_device *drive, void *buffer, unsigned int bytecount)
{
if (drive->channel->atapi_read) {
drive->channel->atapi_read(drive, buffer, bytecount);
......@@ -233,7 +233,7 @@ void atapi_read(ide_drive_t *drive, void *buffer, unsigned int bytecount)
insw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
}
void atapi_write(ide_drive_t *drive, void *buffer, unsigned int bytecount)
void atapi_write(struct ata_device *drive, void *buffer, unsigned int bytecount)
{
if (drive->channel->atapi_write) {
drive->channel->atapi_write(drive, buffer, bytecount);
......@@ -256,7 +256,7 @@ void atapi_write(ide_drive_t *drive, void *buffer, unsigned int bytecount)
/*
* Needed for PCI irq sharing
*/
int drive_is_ready(ide_drive_t *drive)
int drive_is_ready(struct ata_device *drive)
{
byte stat = 0;
if (drive->waiting_for_dma)
......@@ -290,7 +290,7 @@ int drive_is_ready(ide_drive_t *drive)
* Stuff the first sector(s) by implicitly calling the handler driectly
* therafter.
*/
void ata_poll_drive_ready(ide_drive_t *drive)
void ata_poll_drive_ready(struct ata_device *drive)
{
int i;
......@@ -399,7 +399,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
return ide_started;
}
ide_startstop_t ata_taskfile(ide_drive_t *drive,
ide_startstop_t ata_taskfile(struct ata_device *drive,
struct ata_taskfile *args, struct request *rq)
{
struct hd_driveid *id = drive->id;
......@@ -456,39 +456,38 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive,
if (args->prehandler != NULL)
return args->prehandler(drive, rq);
} else {
/*
* FIXME: this is a gross hack, need to unify tcq dma proc and
* regular dma proc -- basically split stuff that needs to act
* on a request from things like ide_dma_check etc.
*/
ide_dma_action_t dma_act;
int tcq = 0;
if (!drive->using_dma)
return ide_started;
/* for dma commands we don't set the handler */
if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
if (args->taskfile.command == WIN_WRITEDMA
|| args->taskfile.command == WIN_WRITEDMA_EXT)
dma_act = ide_dma_write;
else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
else if (args->taskfile.command == WIN_READDMA
|| args->taskfile.command == WIN_READDMA_EXT)
dma_act = ide_dma_read;
else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
tcq = 1;
dma_act = ide_dma_write_queued;
} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
tcq = 1;
dma_act = ide_dma_read_queued;
} else {
#ifdef CONFIG_BLK_DEV_IDE_TCQ
else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
|| args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
|| args->taskfile.command == WIN_READDMA_QUEUED
|| args->taskfile.command == WIN_READDMA_QUEUED_EXT)
return udma_tcq_taskfile(drive, rq);
#endif
else {
printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
return ide_stopped;
}
/*
* FIXME: this is a gross hack, need to unify tcq dma proc and
* regular dma proc -- basically split stuff that needs to act
* on a request from things like ide_dma_check etc.
*/
if (tcq)
return drive->channel->udma(dma_act, drive, rq);
else {
if (drive->channel->udma(dma_act, drive, rq))
return ide_stopped;
}
if (drive->channel->udma(dma_act, drive, rq))
return ide_stopped;
}
return ide_started;
......@@ -900,7 +899,7 @@ void ide_cmd_type_parser(struct ata_taskfile *args)
}
}
int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args, byte *buf)
{
struct request rq;
......@@ -926,7 +925,7 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
* interface.
*/
int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg)
{
int err = 0;
u8 vals[4];
......
......@@ -226,7 +226,7 @@ static void init_hwif_data(struct ata_channel *ch, unsigned int index)
* of the kernel (such as memory allocation) to be functioning yet.
*
* This is too bad, as otherwise we could dynamically allocate the
* ide_drive_t structs as needed, rather than always consuming memory
* ata_device structs as needed, rather than always consuming memory
* for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
*/
#define MAGIC_COOKIE 0x12345678
......@@ -263,24 +263,29 @@ static void __init init_ide_data (void)
* At that time, we might also consider parameterizing the timeouts and retries,
* since these are MUCH faster than mechanical drives. -M.Lord
*/
int drive_is_flashcard (ide_drive_t *drive)
int drive_is_flashcard(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
int i;
char *flashcards[] = {
"KODAK ATA_FLASH",
"Hitachi CV",
"SunDisk SDCFB",
"HAGIWARA HPC",
"LEXAR ATA_FLASH",
"ATA_FLASH" /* Simple Tech */
};
if (drive->removable && id != NULL) {
if (id->config == 0x848a)
return 1; /* CompactFlash */
if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */
|| !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */
|| !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */
|| !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */
|| !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */
|| !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */
{
return 1; /* yes, it is a flash memory card */
}
for (i = 0; i < ARRAY_SIZE(flashcards); i++)
if (!strncmp(id->model, flashcards[i],
strlen(flashcards[i])))
return 1;
}
return 0; /* no, it is not a flash memory card */
return 0;
}
int __ide_end_request(struct ata_device *drive, struct request *rq, int uptodate, int nr_secs)
......@@ -446,7 +451,7 @@ void ide_geninit(struct ata_channel *ch)
}
}
static ide_startstop_t do_reset1(ide_drive_t *, int); /* needed below */
static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
/*
* Poll the interface for completion every 50ms during an ATAPI drive reset
......@@ -546,7 +551,7 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
* for it, we set a timer to poll at 50ms intervals.
*/
static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
{
unsigned int unit;
unsigned long flags;
......@@ -614,7 +619,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
return ide_started;
}
static inline u32 read_24 (ide_drive_t *drive)
static inline u32 read_24(struct ata_device *drive)
{
return (IN_BYTE(IDE_HCYL_REG)<<16) |
(IN_BYTE(IDE_LCYL_REG)<<8) |
......@@ -678,7 +683,7 @@ void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err)
/*
* Error reporting, in human readable form (luxurious, but a memory hog).
*/
byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat)
{
unsigned long flags;
byte err = 0;
......@@ -770,7 +775,7 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
* condition by reading a sector's worth of data from the drive. Of course,
* this may not help if the drive is *waiting* for data from *us*.
*/
static void try_to_flush_leftover_data (ide_drive_t *drive)
static void try_to_flush_leftover_data(struct ata_device *drive)
{
int i;
......@@ -787,7 +792,7 @@ static void try_to_flush_leftover_data (ide_drive_t *drive)
/*
* Take action based on the error returned by the drive.
*/
ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
ide_startstop_t ide_error(struct ata_device *drive, const char *msg, byte stat)
{
struct request *rq;
byte err;
......@@ -844,7 +849,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
/*
* Issue a simple drive command. The drive must be selected beforehand.
*/
void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler)
void ide_cmd(struct ata_device *drive, byte cmd, byte nsect, ata_handler_t handler)
{
ide_set_handler (drive, handler, WAIT_CMD, NULL);
if (IDE_CONTROL_REG)
......@@ -889,7 +894,7 @@ static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *
* setting a timer to wake up at half second intervals thereafter, until
* timeout is achieved, before timing out.
*/
int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
int ide_wait_stat(ide_startstop_t *startstop, struct ata_device *drive, byte good, byte bad, unsigned long timeout) {
byte stat;
int i;
unsigned long flags;
......@@ -933,7 +938,7 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byt
/*
* This initiates handling of a new I/O request.
*/
static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
static ide_startstop_t start_request(struct ata_device *drive, struct request *rq)
{
sector_t block;
unsigned int minor = minor(rq->rq_dev);
......@@ -1081,7 +1086,7 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
ide_startstop_t restart_request(ide_drive_t *drive)
ide_startstop_t restart_request(struct ata_device *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long flags;
......@@ -1100,7 +1105,7 @@ ide_startstop_t restart_request(ide_drive_t *drive)
* This is used by a drive to give excess bandwidth back to the hwgroup by
* sleeping for timeout jiffies.
*/
void ide_stall_queue(ide_drive_t *drive, unsigned long timeout)
void ide_stall_queue(struct ata_device *drive, unsigned long timeout)
{
if (timeout > WAIT_WORSTCASE)
timeout = WAIT_WORSTCASE;
......@@ -1681,10 +1686,10 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
}
/*
* get_info_ptr() returns the (ide_drive_t *) for a given device number.
* get_info_ptr() returns the (struct ata_device *) for a given device number.
* It returns NULL if the given device number does not match any present drives.
*/
ide_drive_t *get_info_ptr(kdev_t i_rdev)
struct ata_device *get_info_ptr(kdev_t i_rdev)
{
unsigned int major = major(i_rdev);
int h;
......@@ -2012,25 +2017,13 @@ void ide_unregister(struct ata_channel *ch)
if (ch->straight8) {
release_region(ch->io_ports[IDE_DATA_OFFSET], 8);
} else {
if (ch->io_ports[IDE_DATA_OFFSET])
release_region(ch->io_ports[IDE_DATA_OFFSET], 1);
if (ch->io_ports[IDE_ERROR_OFFSET])
release_region(ch->io_ports[IDE_ERROR_OFFSET], 1);
if (ch->io_ports[IDE_NSECTOR_OFFSET])
release_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1);
if (ch->io_ports[IDE_SECTOR_OFFSET])
release_region(ch->io_ports[IDE_SECTOR_OFFSET], 1);
if (ch->io_ports[IDE_LCYL_OFFSET])
release_region(ch->io_ports[IDE_LCYL_OFFSET], 1);
if (ch->io_ports[IDE_HCYL_OFFSET])
release_region(ch->io_ports[IDE_HCYL_OFFSET], 1);
if (ch->io_ports[IDE_SELECT_OFFSET])
release_region(ch->io_ports[IDE_SELECT_OFFSET], 1);
if (ch->io_ports[IDE_STATUS_OFFSET])
release_region(ch->io_ports[IDE_STATUS_OFFSET], 1);
for (i = 0; i < 8; i++)
if (ch->io_ports[i])
release_region(ch->io_ports[i], 1);
}
if (ch->io_ports[IDE_CONTROL_OFFSET])
release_region(ch->io_ports[IDE_CONTROL_OFFSET], 1);
/* FIXME: check if we can remove this ifdef */
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (ch->io_ports[IDE_IRQ_OFFSET])
release_region(ch->io_ports[IDE_IRQ_OFFSET], 1);
......@@ -2129,7 +2122,6 @@ void ide_unregister(struct ata_channel *ch)
ch->intrproc = old.intrproc;
ch->maskproc = old.maskproc;
ch->quirkproc = old.quirkproc;
ch->rwproc = old.rwproc;
ch->ata_read = old.ata_read;
ch->ata_write = old.ata_write;
ch->atapi_read = old.atapi_read;
......@@ -2172,24 +2164,18 @@ void ide_setup_ports ( hw_regs_t *hw,
int i;
for (i = 0; i < IDE_NR_PORTS; i++) {
if (offsets[i] == -1) {
switch(i) {
case IDE_CONTROL_OFFSET:
hw->io_ports[i] = ctrl;
break;
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
case IDE_IRQ_OFFSET:
hw->io_ports[i] = intr;
break;
#endif
default:
hw->io_ports[i] = 0;
break;
}
} else {
if (offsets[i] != -1)
hw->io_ports[i] = base + offsets[i];
}
else
hw->io_ports[i] = 0;
}
if (offsets[IDE_CONTROL_OFFSET] == -1)
hw->io_ports[IDE_CONTROL_OFFSET] = ctrl;
/* FIMXE: check if we can remove this ifdef */
#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
if (offsets[IDE_IRQ_OFFSET] == -1)
hw->io_ports[IDE_IRQ_OFFSET] = intr;
#endif
hw->irq = irq;
hw->dma = NO_DMA;
hw->ack_intr = ack_intr;
......@@ -2261,7 +2247,7 @@ int ide_register(int arg1, int arg2, int irq)
return ide_register_hw(&hw, NULL);
}
void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
void ide_add_setting(struct ata_device *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
{
ide_settings_t **p = &drive->settings;
ide_settings_t *setting = NULL;
......@@ -2288,7 +2274,7 @@ void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioct
kfree(setting);
}
void ide_remove_setting (ide_drive_t *drive, char *name)
void ide_remove_setting(struct ata_device *drive, char *name)
{
ide_settings_t **p = &drive->settings, *setting;
......@@ -2301,7 +2287,7 @@ void ide_remove_setting (ide_drive_t *drive, char *name)
kfree(setting);
}
static void auto_remove_settings (ide_drive_t *drive)
static void auto_remove_settings(struct ata_device *drive)
{
ide_settings_t *setting;
repeat:
......@@ -2315,10 +2301,10 @@ static void auto_remove_settings (ide_drive_t *drive)
}
}
int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
int ide_read_setting(struct ata_device *drive, ide_settings_t *setting)
{
int val = -EINVAL;
unsigned long flags;
int val = -EINVAL;
unsigned long flags;
if ((setting->rw & SETTING_READ)) {
spin_lock_irqsave(&ide_lock, flags);
......@@ -2339,7 +2325,7 @@ int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
return val;
}
int ide_spin_wait_hwgroup (ide_drive_t *drive)
int ide_spin_wait_hwgroup(struct ata_device *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long timeout = jiffies + (3 * HZ);
......@@ -2367,7 +2353,7 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
* to the driver to change settings, and then wait on a semaphore for completion.
* The current scheme of polling is kludgey, though safe enough.
*/
int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
int ide_write_setting(struct ata_device *drive, ide_settings_t *setting, int val)
{
int i;
u32 *p;
......@@ -2412,7 +2398,7 @@ static int set_io_32bit(struct ata_device *drive, int arg)
return 0;
}
static int set_using_dma(ide_drive_t *drive, int arg)
static int set_using_dma(struct ata_device *drive, int arg)
{
if (!drive->driver)
return -EPERM;
......@@ -2423,7 +2409,7 @@ static int set_using_dma(ide_drive_t *drive, int arg)
return 0;
}
static int set_pio_mode(ide_drive_t *drive, int arg)
static int set_pio_mode(struct ata_device *drive, int arg)
{
struct request rq;
......@@ -2441,7 +2427,7 @@ static int set_pio_mode(ide_drive_t *drive, int arg)
return 0;
}
void ide_add_generic_settings (ide_drive_t *drive)
void ide_add_generic_settings(struct ata_device *drive)
{
/* drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */
ide_add_setting(drive, "io_32bit", drive->channel->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->channel->io_32bit, set_io_32bit);
......@@ -2476,7 +2462,7 @@ void ide_delay_50ms (void)
static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int err = 0, major, minor;
ide_drive_t *drive;
struct ata_device *drive;
struct request rq;
kdev_t dev;
ide_settings_t *setting;
......@@ -2630,7 +2616,7 @@ static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
static int ide_check_media_change (kdev_t i_rdev)
{
ide_drive_t *drive;
struct ata_device *drive;
int res = 0; /* not changed */
drive = get_info_ptr(i_rdev);
......@@ -2828,7 +2814,7 @@ int __init ide_setup (char *s)
{
int i, vals[3];
struct ata_channel *hwif;
ide_drive_t *drive;
struct ata_device *drive;
unsigned int hw, unit;
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
const char max_hwif = '0' + (MAX_HWIFS - 1);
......@@ -3144,7 +3130,7 @@ int ide_end_request(struct ata_device *drive, struct request *rq, int uptodate)
/*
* Lookup ATA devices, which requested a particular driver.
*/
ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
struct ata_device *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
{
unsigned int unit, index, i;
......@@ -3171,7 +3157,7 @@ ide_drive_t *ide_scan_devices(byte type, const char *name, struct ata_operations
/*
* This is in fact registering a drive not a driver.
*/
int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver)
int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driver)
{
unsigned long flags;
......@@ -3204,7 +3190,7 @@ int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver)
drive->channel->udma(ide_dma_off_quietly, drive, NULL);
drive->channel->udma(ide_dma_check, drive, NULL);
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
drive->channel->udma(ide_dma_queued_on, drive, NULL);
udma_tcq_enable(drive, 1);
#endif
}
......@@ -3238,7 +3224,7 @@ int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver)
*
* FIXME: Check whatever we maybe don't call it twice!.
*/
int ide_unregister_subdriver(ide_drive_t *drive)
int ide_unregister_subdriver(struct ata_device *drive)
{
unsigned long flags;
......
......@@ -93,7 +93,7 @@ static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, stru
dma_stat = inb(hwif->dma_base+2);
outb(inb(hwif->dma_base)&~1, hwif->dma_base); /* stop DMA */
outb(inb(hwif->dma_base)|6, hwif->dma_base); /* from ERRATA: clear the INTR & ERROR bits */
ide_destroy_dmatable(drive); /* and free any DMA resources */
udma_destroy_table(hwif); /* and free any DMA resources */
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_write:
case ide_dma_read:
......
......@@ -215,6 +215,8 @@ static int wait_altstat(struct ata_device *drive, u8 *stat, u8 busy_mask)
return 0;
}
static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq);
/*
* issue SERVICE command to drive -- drive must have been selected first,
* and it must have reported a need for service (status has SERVICE_STAT set)
......@@ -296,7 +298,7 @@ static ide_startstop_t service(struct ata_device *drive)
* interrupt to indicate end of transfer, release is not allowed
*/
TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
return drive->channel->udma(ide_dma_queued_start, drive, rq);
return udma_tcq_start(drive, rq);
}
static ide_startstop_t check_service(struct ata_device *drive)
......@@ -483,11 +485,119 @@ static int configure_tcq(struct ata_device *drive)
return 0;
}
static int tcq_wait_dataphase(struct ata_device *drive)
{
u8 stat;
int i;
while ((stat = GET_STAT()) & BUSY_STAT)
udelay(10);
if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
return 0;
i = 0;
udelay(1);
while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
if (unlikely(i++ > IDE_TCQ_WAIT))
return 1;
udelay(10);
}
return 0;
}
/****************************************************************************
* UDMA transfer handling functions.
*/
/*
* for now assume that command list is always as big as we need and don't
* attempt to shrink it on tcq disable
* Invoked from a SERVICE interrupt, command etc already known. Just need to
* start the dma engine for this tag.
*/
static int enable_queued(struct ata_device *drive, int on)
static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
TCQ_PRINTK("%s: setting up queued %d\n", __FUNCTION__, rq->tag);
if (!test_bit(IDE_BUSY, &ch->hwgroup->flags))
printk("queued_rw: IDE_BUSY not set\n");
if (tcq_wait_dataphase(drive))
return ide_stopped;
if (ata_start_dma(drive, rq))
return ide_stopped;
set_irq(drive, ide_dmaq_intr);
if (!ch->udma(ide_dma_begin, drive, rq))
return ide_started;
return ide_stopped;
}
/*
* Start a queued command from scratch.
*/
ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
{
u8 stat;
u8 feat;
struct ata_taskfile *args = rq->special;
TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
/*
* set nIEN, tag start operation will enable again when
* it is safe
*/
drive_ctl_nien(drive, 1);
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
if (wait_altstat(drive, &stat, BUSY_STAT)) {
ide_dump_status(drive, "queued start", stat);
tcq_invalidate_queue(drive);
return ide_stopped;
}
drive_ctl_nien(drive, 0);
if (stat & ERR_STAT) {
ide_dump_status(drive, "tcq_start", stat);
return ide_stopped;
}
/*
* drive released the bus, clear active tag and
* check for service
*/
if ((feat = GET_FEAT()) & NSEC_REL) {
drive->immed_rel++;
HWGROUP(drive)->rq = NULL;
set_irq(drive, ide_dmaq_intr);
TCQ_PRINTK("REL in queued_start\n");
if ((stat = GET_STAT()) & SERVICE_STAT)
return service(drive);
return ide_released;
}
TCQ_PRINTK("IMMED in queued_start\n");
drive->immed_comp++;
return udma_tcq_start(drive, rq);
}
/*
* For now assume that command list is always as big as we need and don't
* attempt to shrink it on tcq disable.
*/
int udma_tcq_enable(struct ata_device *drive, int on)
{
int depth = drive->using_tcq ? drive->queue_depth : 0;
......@@ -523,120 +633,3 @@ static int enable_queued(struct ata_device *drive, int on)
drive->using_tcq = 1;
return 0;
}
static int tcq_wait_dataphase(struct ata_device *drive)
{
u8 stat;
int i;
while ((stat = GET_STAT()) & BUSY_STAT)
udelay(10);
if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
return 0;
i = 0;
udelay(1);
while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
if (unlikely(i++ > IDE_TCQ_WAIT))
return 1;
udelay(10);
}
return 0;
}
ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
unsigned int enable_tcq = 1;
u8 stat;
u8 feat;
switch (func) {
/*
* invoked from a SERVICE interrupt, command etc already known.
* just need to start the dma engine for this tag
*/
case ide_dma_queued_start:
TCQ_PRINTK("ide_dma: setting up queued %d\n", rq->tag);
if (!test_bit(IDE_BUSY, &HWGROUP(drive)->flags))
printk("queued_rw: IDE_BUSY not set\n");
if (tcq_wait_dataphase(drive))
return ide_stopped;
if (ide_start_dma(func, drive))
return ide_stopped;
set_irq(drive, ide_dmaq_intr);
if (!hwif->udma(ide_dma_begin, drive, rq))
return ide_started;
return ide_stopped;
/*
* start a queued command from scratch
*/
case ide_dma_read_queued:
case ide_dma_write_queued: {
struct ata_taskfile *args = rq->special;
TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
/*
* set nIEN, tag start operation will enable again when
* it is safe
*/
drive_ctl_nien(drive, 1);
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
if (wait_altstat(drive, &stat, BUSY_STAT)) {
ide_dump_status(drive, "queued start", stat);
tcq_invalidate_queue(drive);
return ide_stopped;
}
drive_ctl_nien(drive, 0);
if (stat & ERR_STAT) {
ide_dump_status(drive, "tcq_start", stat);
return ide_stopped;
}
/*
* drive released the bus, clear active tag and
* check for service
*/
if ((feat = GET_FEAT()) & NSEC_REL) {
drive->immed_rel++;
HWGROUP(drive)->rq = NULL;
set_irq(drive, ide_dmaq_intr);
TCQ_PRINTK("REL in queued_start\n");
if ((stat = GET_STAT()) & SERVICE_STAT)
return service(drive);
return ide_released;
}
TCQ_PRINTK("IMMED in queued_start\n");
drive->immed_comp++;
return hwif->udma(ide_dma_queued_start, drive, rq);
}
case ide_dma_queued_off:
enable_tcq = 0;
case ide_dma_queued_on:
if (enable_tcq && !drive->using_dma)
return 1;
return enable_queued(drive, enable_tcq);
default:
break;
}
return 1;
}
......@@ -175,7 +175,7 @@ static void trm290_selectproc (ide_drive_t *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA
static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
{
struct ata_channel *hwif = drive->channel;
struct ata_channel *ch = drive->channel;
unsigned int count, reading = 2, writing = 0;
switch (func) {
......@@ -186,12 +186,12 @@ static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, stru
break; /* always use PIO for writes */
#endif
case ide_dma_read:
if (!(count = ide_build_dmatable(drive, func)))
if (!(count = udma_new_table(ch, rq)))
break; /* try PIO instead of DMA */
trm290_prepare_drive(drive, 1); /* select DMA xfer */
outl(hwif->dmatable_dma|reading|writing, hwif->dma_base);
outl(ch->dmatable_dma|reading|writing, ch->dma_base);
drive->waiting_for_dma = 1;
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
......@@ -201,10 +201,10 @@ static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, stru
return 0;
case ide_dma_end:
drive->waiting_for_dma = 0;
ide_destroy_dmatable(drive); /* purge DMA mappings */
return (inw(hwif->dma_base+2) != 0x00ff);
udma_destroy_table(ch); /* purge DMA mappings */
return (inw(ch->dma_base + 2) != 0x00ff);
case ide_dma_test_irq:
return (inw(hwif->dma_base+2) == 0x00ff);
return (inw(ch->dma_base + 2) == 0x00ff);
default:
return ide_dmaproc(func, drive, rq);
}
......
......@@ -367,32 +367,24 @@ struct ata_device {
/*
* tcq statistics
*/
unsigned long immed_rel;
unsigned long immed_rel;
unsigned long immed_comp;
int max_last_depth;
int max_depth;
} ide_drive_t;
/*
* This initiates/aborts DMA read/write operations on a drive.
*
* The caller is assumed to have selected the drive and programmed the drive's
* sector address using CHS or LBA. All that remains is to prepare for DMA
* and then issue the actual read/write DMA/PIO command to the drive.
*
* Returns 0 if all went well.
* Returns 1 if DMA read/write could not be started, in which case the caller
* should either try again later, or revert to PIO for the current request.
*/
typedef enum { ide_dma_read, ide_dma_write, ide_dma_begin,
ide_dma_end, ide_dma_check, ide_dma_on,
ide_dma_off, ide_dma_off_quietly, ide_dma_test_irq,
ide_dma_bad_drive, ide_dma_good_drive,
ide_dma_verbose, ide_dma_retune,
ide_dma_lostirq, ide_dma_timeout,
ide_dma_read_queued, ide_dma_write_queued,
ide_dma_queued_start, ide_dma_queued_on,
ide_dma_queued_off,
typedef enum {
ide_dma_read, ide_dma_write,
ide_dma_begin, ide_dma_end,
ide_dma_check,
ide_dma_on, ide_dma_off,
ide_dma_off_quietly,
ide_dma_test_irq,
ide_dma_bad_drive,
ide_dma_good_drive,
ide_dma_retune,
ide_dma_lostirq,
ide_dma_timeout
} ide_dma_action_t;
enum {
......@@ -435,9 +427,6 @@ struct ata_channel {
/* special host masking for drive selection */
void (*maskproc) (struct ata_device *, int);
/* adjust timing based upon rq->cmd direction */
void (*rwproc) (struct ata_device *, ide_dma_action_t);
/* check host's drive quirk list */
int (*quirkproc) (struct ata_device *);
......@@ -471,6 +460,7 @@ struct ata_channel {
unsigned autodma : 1; /* automatically try to enable DMA at boot */
unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
unsigned highmem : 1; /* can do full 32-bit dma */
unsigned straight8 : 1; /* Alan's straight 8 check */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
unsigned no_unmask : 1; /* disallow setting unmask bit */
unsigned auto_poll : 1; /* supports nop auto-poll */
......@@ -481,8 +471,8 @@ struct ata_channel {
#if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */
#endif
byte straight8; /* Alan's straight 8 check */
int (*busproc)(struct ata_device *, int); /* driver soft-power interface */
/* driver soft-power interface */
int (*busproc)(struct ata_device *, int);
byte bus_state; /* power state of the IDE bus */
};
......@@ -561,7 +551,7 @@ typedef struct hwgroup_s {
#define SETTING_WRITE (1 << 1)
#define SETTING_RW (SETTING_READ | SETTING_WRITE)
typedef int (ide_procset_t)(ide_drive_t *, int);
typedef int (ide_procset_t)(struct ata_device *, int);
typedef struct ide_settings_s {
char *name;
int rw;
......@@ -578,11 +568,11 @@ typedef struct ide_settings_s {
struct ide_settings_s *next;
} ide_settings_t;
void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
void ide_remove_setting(ide_drive_t *drive, char *name);
int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
void ide_add_generic_settings(ide_drive_t *drive);
extern void ide_add_setting(struct ata_device *, const char *, int, int, int, int, int, int, int, int, void *, ide_procset_t *);
extern void ide_remove_setting(struct ata_device *, char *);
extern int ide_read_setting(struct ata_device *, ide_settings_t *);
extern int ide_write_setting(struct ata_device *, ide_settings_t *, int);
extern void ide_add_generic_settings(struct ata_device *);
/*
* /proc/ide interface
......@@ -695,19 +685,19 @@ extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
/*
* Error reporting, in human readable form (luxurious, but a memory hog).
*/
byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat);
extern byte ide_dump_status(struct ata_device *, const char *, byte);
/*
* ide_error() takes action based on the error returned by the controller.
* The caller should return immediately after invoking this.
*/
ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
extern ide_startstop_t ide_error(struct ata_device *, const char *, byte);
/*
* Issue a simple drive command
* The drive must be selected beforehand.
*/
void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler);
void ide_cmd(struct ata_device *, byte, byte, ata_handler_t);
/*
* ide_fixstring() cleans up and (optionally) byte-swaps a text string,
......@@ -725,9 +715,9 @@ void ide_fixstring(byte *s, const int bytecount, const int byteswap);
* caller should return the updated value of "startstop" in this case.
* "startstop" is unchanged when the function returns 0;
*/
int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
extern int ide_wait_stat(ide_startstop_t *, struct ata_device *, byte, byte, unsigned long);
int ide_wait_noerr(ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
/*
* This routine is called from the partition-table code in genhd.c
......@@ -736,15 +726,15 @@ int ide_wait_noerr(ide_drive_t *drive, byte good, byte bad, unsigned long timeou
int ide_xlate_1024(kdev_t, int, int, const char *);
/*
* Convert kdev_t structure into ide_drive_t * one.
* Convert kdev_t structure into struct ata_device * one.
*/
ide_drive_t *get_info_ptr(kdev_t i_rdev);
struct ata_device *get_info_ptr(kdev_t i_rdev);
/*
* Re-Start an operation for an IDE interface.
* The caller should return immediately after invoking this.
*/
ide_startstop_t restart_request(ide_drive_t *);
ide_startstop_t restart_request(struct ata_device *);
/*
* This function is intended to be used prior to invoking ide_do_drive_cmd().
......@@ -766,12 +756,12 @@ typedef enum {
*/
#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);
/*
* Clean up after success/failure of an explicit drive cmd.
*/
void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
extern void ide_end_drive_cmd(struct ata_device *, byte, byte);
struct ata_taskfile {
struct hd_drive_task_hdr taskfile;
......@@ -808,31 +798,20 @@ extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg);
void ide_delay_50ms(void);
byte ide_auto_reduce_xfer (ide_drive_t *drive);
int ide_driveid_update (ide_drive_t *drive);
int ide_ata66_check (ide_drive_t *drive, struct ata_taskfile *args);
int ide_config_drive_speed (ide_drive_t *drive, byte speed);
byte eighty_ninty_three (ide_drive_t *drive);
int set_transfer (ide_drive_t *drive, struct ata_taskfile *args);
extern byte ide_auto_reduce_xfer(struct ata_device *);
extern int ide_driveid_update(struct ata_device *);
extern int ide_ata66_check(struct ata_device *, struct ata_taskfile *);
extern int ide_config_drive_speed(struct ata_device *, byte);
extern byte eighty_ninty_three(struct ata_device *);
extern int set_transfer(struct ata_device *, struct ata_taskfile *);
extern int system_bus_speed;
/*
* idedisk_input_data() is a wrapper around ide_input_data() which copes
* with byte-swapping the input data if required.
*/
extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
/*
* ide_stall_queue() can be used by a drive to give excess bandwidth back
* to the hwgroup by sleeping for timeout jiffies.
*/
void ide_stall_queue (ide_drive_t *drive, unsigned long timeout);
/*
* ide_get_queue() returns the queue which corresponds to a given device.
*/
request_queue_t *ide_get_queue(kdev_t dev);
void ide_stall_queue(struct ata_device *, unsigned long);
/*
* CompactFlash cards and their brethern pretend to be removable hard disks,
......@@ -841,9 +820,9 @@ request_queue_t *ide_get_queue(kdev_t dev);
* config bits.
*/
extern int drive_is_flashcard(ide_drive_t *drive);
extern int drive_is_flashcard(struct ata_device *);
int ide_spin_wait_hwgroup (ide_drive_t *drive);
int ide_spin_wait_hwgroup(struct ata_device *);
void ide_timer_expiry (unsigned long data);
extern void ata_irq_request(int irq, void *data, struct pt_regs *regs);
void do_ide_request (request_queue_t * q);
......@@ -889,15 +868,21 @@ extern int ide_unregister_subdriver(struct ata_device *drive);
void __init ide_scan_pcibus(int scan_direction);
#endif
#ifdef CONFIG_BLK_DEV_IDEDMA
extern int ide_build_dmatable(struct ata_device *, ide_dma_action_t);
extern void ide_destroy_dmatable(struct ata_device *);
extern int udma_new_table(struct ata_channel *, struct request *);
extern void udma_destroy_table(struct ata_channel *);
extern void udma_print(struct ata_device *);
extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
extern int udma_tcq_enable(struct ata_device *, int);
extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
extern int check_drive_lists(struct ata_device *, int good_bad);
extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
extern void ide_release_dma(struct ata_channel *);
extern void ide_setup_dma(struct ata_channel *, unsigned long, unsigned int) __init;
extern int ide_start_dma(ide_dma_action_t, struct ata_device *);
extern int ata_start_dma(struct ata_device *, struct request *rq);
#endif
extern spinlock_t ide_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment