--- zzzz-none-000/linux-2.4.17/drivers/ide/icside.c 2001-10-25 20:53:47.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/ide/icside.c 2004-11-24 13:23:45.000000000 +0000 @@ -27,6 +27,7 @@ #include extern char *ide_xfer_verbose (byte xfer_rate); +extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); /* * Maximum number of interfaces per card @@ -267,39 +268,56 @@ pci_unmap_sg(NULL, sg, nents, HWIF(drive)->sg_dma_direction); } +/* + * Configure the IOMD to give the appropriate timings for the transfer + * mode being requested. We take the advice of the ATA standards, and + * calculate the cycle time based on the transfer mode, and the EIDE + * MW DMA specs that the drive provides in the IDENTIFY command. + * + * We have the following IOMD DMA modes to choose from: + * + * Type Active Recovery Cycle + * A 250 (250) 312 (550) 562 (800) + * B 187 250 437 + * C 125 (125) 125 (375) 250 (500) + * D 62 125 187 + * + * (figures in brackets are actual measured timings) + * + * However, we also need to take care of the read/write active and + * recovery timings: + * + * Read Write + * Mode Active -- Recovery -- Cycle IOMD type + * MW0 215 50 215 480 A + * MW1 80 50 50 150 C + * MW2 70 25 25 120 C + */ static int icside_config_if(ide_drive_t *drive, int xfer_mode) { int func = ide_dma_off; + int cycle_time = 0, use_dma_info = 0; switch (xfer_mode) { - case XFER_MW_DMA_2: - /* - * The cycle time is limited to 250ns by the r/w - * pulse width (90ns), however we should still - * have a maximum burst transfer rate of 8MB/s. - */ - drive->drive_data = 250; - break; - - case XFER_MW_DMA_1: - drive->drive_data = 250; - break; + case XFER_MW_DMA_2: cycle_time = 250; use_dma_info = 1; break; + case XFER_MW_DMA_1: cycle_time = 250; use_dma_info = 1; break; + case XFER_MW_DMA_0: cycle_time = 480; break; + } - case XFER_MW_DMA_0: - drive->drive_data = 480; - break; + /* + * If we're going to be doing MW_DMA_1 or MW_DMA_2, we should + * take care to note the values in the ID... + */ + if (use_dma_info && drive->id->eide_dma_time > cycle_time) + cycle_time = drive->id->eide_dma_time; - default: - drive->drive_data = 0; - break; - } + drive->drive_data = cycle_time; if (!drive->init_speed) - drive->init_speed = (byte) xfer_mode; + drive->init_speed = xfer_mode; - if (drive->drive_data && - ide_config_drive_speed(drive, (byte) xfer_mode) == 0) + if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0) func = ide_dma_on; else drive->drive_data = 480; @@ -307,7 +325,7 @@ printk("%s: %s selected (peak %dMB/s)\n", drive->name, ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); - drive->current_speed = (byte) xfer_mode; + drive->current_speed = xfer_mode; return func; } @@ -414,7 +432,7 @@ * This is setup to be called as an extern for future support * to other special driver code. */ -static int check_drive_lists(ide_drive_t *drive, int good_bad) +static int icside_check_drive_lists(ide_drive_t *drive, int good_bad) { struct hd_driveid *id = drive->id; @@ -444,7 +462,7 @@ /* * Consult the list of known "bad" drives */ - if (check_drive_lists(drive, 0)) { + if (icside_check_drive_lists(drive, 0)) { func = ide_dma_off; goto out; } @@ -469,7 +487,7 @@ /* * Consult the list of known "good" drives */ - if (check_drive_lists(drive, 1)) { + if (icside_check_drive_lists(drive, 1)) { if (id->eide_dma_time > 150) goto out; xfer_mode = XFER_MW_DMA_1; @@ -553,7 +571,8 @@ case ide_dma_bad_drive: case ide_dma_good_drive: - return check_drive_lists(drive, (func == ide_dma_good_drive)); + return icside_check_drive_lists(drive, (func == + ide_dma_good_drive)); case ide_dma_verbose: return icside_dma_verbose(drive); @@ -591,6 +610,15 @@ printk(" -- ERROR, unable to allocate DMA table\n"); return 0; } + +int ide_release_dma(ide_hwif_t *hwif) +{ + if (hwif->sg_table) { + kfree(hwif->sg_table); + hwif->sg_table = NULL; + } + return 1; +} #endif static ide_hwif_t *