Commit 045c90fe authored by Martin Dalecki's avatar Martin Dalecki Committed by Kai Germaschewski

[PATCH] 2.5.10 IDE 44

Reduce the "rain forest" of pointers a bit.

- Use the channel info from the drive instead of from hwgroup where possible.
   Since we have now a direct association between a channel and irq, we can fix
   the handler for unexpected interrupts to don't have to iterate over multiple
   possibilities.

- Finally it was just possible to remove the circular list of channels
   associated with a hwif. The hwif member of struct hwgroup_s as well as
   next member if struct ata_channel are gone.

- Unify ide_build_sglist() and raw_build_sglist() in to one function.  Use the
   queue associated with a request in the case of a CMD request there instead of
   referencing the device minor number. This will be pushed even further later.
parent 5ef2759c
...@@ -27,7 +27,9 @@ volatile struct baboon *baboon; ...@@ -27,7 +27,9 @@ volatile struct baboon *baboon;
void baboon_irq(int, void *, struct pt_regs *); void baboon_irq(int, void *, struct pt_regs *);
#if 0
extern int macide_ack_intr(struct ata_channel *); extern int macide_ack_intr(struct ata_channel *);
#endif
/* /*
* Baboon initialization. * Baboon initialization.
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
* May be copied or modified under the terms of the GNU General Public License * May be copied or modified under the terms of the GNU General Public License
* *
* Special Thanks to Mark for his Six years of work. * Special Thanks to Mark for his Six years of work.
*/ *
/*
* This module provides support for the bus-master IDE DMA functions * This module provides support for the bus-master IDE DMA functions
* of various PCI chipsets, including the Intel PIIX (i82371FB for * of various PCI chipsets, including the Intel PIIX (i82371FB for
* the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and
...@@ -209,71 +207,68 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) ...@@ -209,71 +207,68 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
__ide_end_request(drive, 1, rq->nr_sectors); __ide_end_request(drive, 1, rq->nr_sectors);
return ide_stopped; return ide_stopped;
} }
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat); drive->name, dma_stat);
} }
return ide_error(drive, "dma_intr", stat); return ide_error(drive, "dma_intr", stat);
} }
static int ide_build_sglist(struct ata_channel *hwif, struct request *rq)
{
request_queue_t *q = &hwif->drives[DEVICE_NR(rq->rq_dev) & 1].queue;
struct scatterlist *sg = hwif->sg_table;
int nents;
nents = blk_rq_map_sg(q, rq, hwif->sg_table);
if (rq->q && nents > rq->nr_phys_segments)
printk("ide-dma: received %d phys segments, build %d\n", rq->nr_phys_segments, nents);
if (rq_data_dir(rq) == READ)
hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
else
hwif->sg_dma_direction = PCI_DMA_TODEVICE;
return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
}
/* /*
* FIXME: taskfiles should be a map of pages, not a long virt address... /jens * FIXME: taskfiles should be a map of pages, not a long virt address... /jens
* FIXME: I agree with Jens --mdcki! * FIXME: I agree with Jens --mdcki!
*/ */
static int raw_build_sglist(struct ata_channel *ch, struct request *rq) static int build_sglist(struct ata_channel *ch, struct request *rq)
{ {
struct scatterlist *sg = ch->sg_table; struct scatterlist *sg = ch->sg_table;
int nents = 0; int nents = 0;
struct ata_taskfile *args = rq->special;
if (rq->flags & REQ_DRIVE_ACB) {
struct ata_taskfile *args = rq->special;
#if 1 #if 1
unsigned char *virt_addr = rq->buffer; unsigned char *virt_addr = rq->buffer;
int sector_count = rq->nr_sectors; int sector_count = rq->nr_sectors;
#else #else
nents = blk_rq_map_sg(rq->q, rq, ch->sg_table); nents = blk_rq_map_sg(rq->q, rq, ch->sg_table);
if (nents > rq->nr_segments) if (nents > rq->nr_segments)
printk("ide-dma: received %d segments, build %d\n", rq->nr_segments, nents); printk("ide-dma: received %d segments, build %d\n", rq->nr_segments, nents);
#endif #endif
if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
ch->sg_dma_direction = PCI_DMA_TODEVICE; ch->sg_dma_direction = PCI_DMA_TODEVICE;
else else
ch->sg_dma_direction = PCI_DMA_FROMDEVICE; ch->sg_dma_direction = PCI_DMA_FROMDEVICE;
if (sector_count > 128) { /*
* FIXME: This depends upon a hard coded page size!
*/
if (sector_count > 128) {
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
sg[nents].length = 128 * SECTOR_SIZE;
++nents;
virt_addr = virt_addr + (128 * SECTOR_SIZE);
sector_count -= 128;
}
memset(&sg[nents], 0, sizeof(*sg)); memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr); sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
sg[nents].length = 128 * SECTOR_SIZE; sg[nents].length = sector_count * SECTOR_SIZE;
nents++; ++nents;
virt_addr = virt_addr + (128 * SECTOR_SIZE); } else {
sector_count -= 128; nents = blk_rq_map_sg(rq->q, rq, ch->sg_table);
}
memset(&sg[nents], 0, sizeof(*sg));
sg[nents].page = virt_to_page(virt_addr);
sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
sg[nents].length = sector_count * SECTOR_SIZE;
nents++;
if (rq->q && nents > rq->nr_phys_segments)
printk("ide-dma: received %d phys segments, build %d\n", rq->nr_phys_segments, nents);
if (rq_data_dir(rq) == READ)
ch->sg_dma_direction = PCI_DMA_FROMDEVICE;
else
ch->sg_dma_direction = PCI_DMA_TODEVICE;
}
return pci_map_sg(ch->pci_dev, sg, nents, ch->sg_dma_direction); return pci_map_sg(ch->pci_dev, sg, nents, ch->sg_dma_direction);
} }
...@@ -295,11 +290,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) ...@@ -295,11 +290,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
int i; int i;
struct scatterlist *sg; struct scatterlist *sg;
if (HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) { hwif->sg_nents = i = build_sglist(hwif, HWGROUP(drive)->rq);
hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq);
} else {
hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
}
if (!i) if (!i)
return 0; return 0;
...@@ -333,7 +324,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) ...@@ -333,7 +324,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
if (is_trm290_chipset) if (is_trm290_chipset)
xcount = ((xcount >> 2) - 1) << 16; xcount = ((xcount >> 2) - 1) << 16;
if (xcount == 0x0000) { if (xcount == 0x0000) {
/* /*
* Most chipsets correctly interpret a length of * Most chipsets correctly interpret a length of
* 0x0000 as 64KB, but at least one (e.g. CS5530) * 0x0000 as 64KB, but at least one (e.g. CS5530)
* misinterprets it as zero (!). So here we break * misinterprets it as zero (!). So here we break
......
...@@ -633,7 +633,7 @@ static void save_match(struct ata_channel *hwif, struct ata_channel *new, ...@@ -633,7 +633,7 @@ static void save_match(struct ata_channel *hwif, struct ata_channel *new,
static int init_irq(struct ata_channel *ch) static int init_irq(struct ata_channel *ch)
{ {
unsigned long flags; unsigned long flags;
unsigned int index; int i;
ide_hwgroup_t *hwgroup; ide_hwgroup_t *hwgroup;
ide_hwgroup_t *new_hwgroup; ide_hwgroup_t *new_hwgroup;
struct ata_channel *match = NULL; struct ata_channel *match = NULL;
...@@ -650,8 +650,9 @@ static int init_irq(struct ata_channel *ch) ...@@ -650,8 +650,9 @@ static int init_irq(struct ata_channel *ch)
/* /*
* Group up with any other channels that share our irq(s). * Group up with any other channels that share our irq(s).
*/ */
for (index = 0; index < MAX_HWIFS; index++) { for (i = 0; i < MAX_HWIFS; ++i) {
struct ata_channel *h = &ide_hwifs[index]; struct ata_channel *h = &ide_hwifs[i];
if (h->hwgroup) { /* scan only initialized channels */ if (h->hwgroup) { /* scan only initialized channels */
if (ch->irq == h->irq) { if (ch->irq == h->irq) {
ch->sharing_irq = h->sharing_irq = 1; ch->sharing_irq = h->sharing_irq = 1;
...@@ -682,7 +683,6 @@ static int init_irq(struct ata_channel *ch) ...@@ -682,7 +683,6 @@ static int init_irq(struct ata_channel *ch)
return 1; return 1;
} }
memset(hwgroup, 0, sizeof(ide_hwgroup_t)); memset(hwgroup, 0, sizeof(ide_hwgroup_t));
hwgroup->hwif = ch->next = ch;
hwgroup->rq = NULL; hwgroup->rq = NULL;
hwgroup->handler = NULL; hwgroup->handler = NULL;
hwgroup->drive = NULL; hwgroup->drive = NULL;
...@@ -716,14 +716,12 @@ static int init_irq(struct ata_channel *ch) ...@@ -716,14 +716,12 @@ static int init_irq(struct ata_channel *ch)
} }
/* /*
* Everything is okay, so link us into the hwgroup. * Everything is okay.
*/ */
ch->hwgroup = hwgroup; ch->hwgroup = hwgroup;
ch->next = hwgroup->hwif->next;
hwgroup->hwif->next = ch;
for (index = 0; index < MAX_DRIVES; ++index) { for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[index]; struct ata_device *drive = &ch->drives[i];
if (!drive->present) if (!drive->present)
continue; continue;
...@@ -736,12 +734,6 @@ static int init_irq(struct ata_channel *ch) ...@@ -736,12 +734,6 @@ static int init_irq(struct ata_channel *ch)
init_device_queue(drive); init_device_queue(drive);
} }
if (!hwgroup->hwif) {
hwgroup->hwif = hwgroup->drive->channel;
#ifdef DEBUG
printk("%s : Adding missed channel to hwgroup!!\n", ch->name);
#endif
}
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__) #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
...@@ -762,6 +754,7 @@ static int init_irq(struct ata_channel *ch) ...@@ -762,6 +754,7 @@ static int init_irq(struct ata_channel *ch)
printk(" (%sed with %s)", printk(" (%sed with %s)",
ch->sharing_irq ? "shar" : "serializ", match->name); ch->sharing_irq ? "shar" : "serializ", match->name);
printk("\n"); printk("\n");
return 0; return 0;
} }
...@@ -885,7 +878,7 @@ static int hwif_init(struct ata_channel *hwif) ...@@ -885,7 +878,7 @@ static int hwif_init(struct ata_channel *hwif)
printk("%s: probed IRQ %d failed, using default.\n", printk("%s: probed IRQ %d failed, using default.\n",
hwif->name, hwif->irq); hwif->name, hwif->irq);
} }
init_gendisk(hwif); init_gendisk(hwif);
blk_dev[hwif->major].data = hwif; blk_dev[hwif->major].data = hwif;
blk_dev[hwif->major].queue = ide_get_queue; blk_dev[hwif->major].queue = ide_get_queue;
...@@ -898,7 +891,7 @@ int ideprobe_init (void) ...@@ -898,7 +891,7 @@ int ideprobe_init (void)
{ {
unsigned int index; unsigned int index;
int probe[MAX_HWIFS]; int probe[MAX_HWIFS];
memset(probe, 0, MAX_HWIFS * sizeof(int)); memset(probe, 0, MAX_HWIFS * sizeof(int));
for (index = 0; index < MAX_HWIFS; ++index) for (index = 0; index < MAX_HWIFS; ++index)
probe[index] = !ide_hwifs[index].present; probe[index] = !ide_hwifs[index].present;
......
This diff is collapsed.
...@@ -73,7 +73,6 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -73,7 +73,6 @@ typedef unsigned char byte; /* used everywhere */
*/ */
#define DMA_PIO_RETRY 1 /* retrying in PIO */ #define DMA_PIO_RETRY 1 /* retrying in PIO */
#define HWIF(drive) ((drive)->channel)
#define HWGROUP(drive) (drive->channel->hwgroup) #define HWGROUP(drive) (drive->channel->hwgroup)
/* /*
...@@ -254,7 +253,7 @@ void ide_setup_ports(hw_regs_t *hw, ...@@ -254,7 +253,7 @@ void ide_setup_ports(hw_regs_t *hw,
#endif #endif
/* /*
* Now for the data we need to maintain per-drive: ide_drive_t * Device types - the nomenclature is analogous to SCSI code.
*/ */
#define ATA_DISK 0x20 #define ATA_DISK 0x20
...@@ -266,7 +265,10 @@ void ide_setup_ports(hw_regs_t *hw, ...@@ -266,7 +265,10 @@ void ide_setup_ports(hw_regs_t *hw,
#define ATA_NO_LUN 0x7f #define ATA_NO_LUN 0x7f
struct ide_settings_s; struct ide_settings_s;
/* structure describing an ATA/ATAPI device */
/*
* ATA/ATAPI device structure :
*/
typedef typedef
struct ata_device { struct ata_device {
struct ata_channel * channel; struct ata_channel * channel;
...@@ -401,7 +403,6 @@ struct ata_channel { ...@@ -401,7 +403,6 @@ struct ata_channel {
struct device dev; /* device handle */ struct device dev; /* device handle */
int unit; /* channel number */ int unit; /* channel number */
struct ata_channel *next; /* for linked-list in ide_hwgroup_t */
struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */
ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */
...@@ -516,17 +517,14 @@ typedef int (ide_expiry_t)(ide_drive_t *); ...@@ -516,17 +517,14 @@ typedef int (ide_expiry_t)(ide_drive_t *);
#define IDE_DMA 2 /* DMA in progress */ #define IDE_DMA 2 /* DMA in progress */
typedef struct hwgroup_s { typedef struct hwgroup_s {
ide_handler_t *handler;/* irq handler, if active */ ide_handler_t *handler; /* irq handler, if active */
unsigned long flags; /* BUSY, SLEEPING */ unsigned long flags; /* BUSY, SLEEPING */
ide_drive_t *drive; /* current drive */ struct ata_device *drive; /* current drive */
struct ata_channel *hwif; /* ptr to current hwif in linked-list */ struct request *rq; /* current request */
struct timer_list timer; /* failsafe timer */
struct request *rq; /* current request */ struct request wrq; /* local copy of current write rq */
unsigned long poll_timeout; /* timeout value during long polls */
struct timer_list timer; /* failsafe timer */ ide_expiry_t *expiry; /* queried upon timeouts */
struct request wrq; /* local copy of current write rq */
unsigned long poll_timeout; /* timeout value during long polls */
ide_expiry_t *expiry; /* queried upon timeouts */
} ide_hwgroup_t; } ide_hwgroup_t;
/* structure attached to the request for IDE_TASK_CMDS */ /* structure attached to the request for IDE_TASK_CMDS */
......
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