aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/cmd64x.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:08 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-05-09 18:01:08 -0400
commit2d5eaa6dd744a641e75503232a01f52d0768884c (patch)
tree0736bd00ea3bd032d601d0a676c998cb043b877a /drivers/ide/pci/cmd64x.c
parent18137207236285989dfc0ee7f929b954199228f3 (diff)
ide: rework the code for selecting the best DMA transfer mode (v3)
Depends on the "ide: fix UDMA/MWDMA/SWDMA masks" patch. * add ide_hwif_t.udma_filter hook for filtering UDMA mask (use it in alim15x3, hpt366, siimage and serverworks drivers) * add ide_max_dma_mode() for finding best DMA mode for the device (loosely based on some older libata-core.c code) * convert ide_dma_speed() users to use ide_max_dma_mode() * make ide_rate_filter() take "ide_drive_t *drive" as an argument instead of "u8 mode" and teach it to how to use UDMA mask to do filtering * use ide_rate_filter() in hpt366 driver * remove no longer needed ide_dma_speed() and *_ratemask() * unexport eighty_ninty_three() v2: * rename ->filter_udma_mask to ->udma_filter [ Suggested by Sergei Shtylyov <sshtylyov@ru.mvista.com>. ] v3: * updated for scc_pata driver (fixes XFER_UDMA_6 filtering for user-space originated transfer mode change requests when 100MHz clock is used) Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci/cmd64x.c')
-rw-r--r--drivers/ide/pci/cmd64x.c65
1 files changed, 14 insertions, 51 deletions
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 610c45f7b4e2..19f5ac1f866c 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -292,55 +292,6 @@ static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio)
292 (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); 292 (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
293} 293}
294 294
295static u8 cmd64x_ratemask (ide_drive_t *drive)
296{
297 struct pci_dev *dev = HWIF(drive)->pci_dev;
298 u8 mode = 0;
299
300 switch(dev->device) {
301 case PCI_DEVICE_ID_CMD_649:
302 mode = 3;
303 break;
304 case PCI_DEVICE_ID_CMD_648:
305 mode = 2;
306 break;
307 case PCI_DEVICE_ID_CMD_643:
308 return 0;
309
310 case PCI_DEVICE_ID_CMD_646:
311 {
312 unsigned int class_rev = 0;
313 pci_read_config_dword(dev,
314 PCI_CLASS_REVISION, &class_rev);
315 class_rev &= 0xff;
316 /*
317 * UltraDMA only supported on PCI646U and PCI646U2, which
318 * correspond to revisions 0x03, 0x05 and 0x07 respectively.
319 * Actually, although the CMD tech support people won't
320 * tell me the details, the 0x03 revision cannot support
321 * UDMA correctly without hardware modifications, and even
322 * then it only works with Quantum disks due to some
323 * hold time assumptions in the 646U part which are fixed
324 * in the 646U2.
325 *
326 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
327 */
328 switch(class_rev) {
329 case 0x07:
330 case 0x05:
331 return 1;
332 case 0x03:
333 case 0x01:
334 default:
335 return 0;
336 }
337 }
338 }
339 if (!eighty_ninty_three(drive))
340 mode = min(mode, (u8)1);
341 return mode;
342}
343
344static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) 295static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed)
345{ 296{
346 ide_hwif_t *hwif = HWIF(drive); 297 ide_hwif_t *hwif = HWIF(drive);
@@ -348,7 +299,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed)
348 u8 unit = drive->dn & 0x01; 299 u8 unit = drive->dn & 0x01;
349 u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; 300 u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0;
350 301
351 speed = ide_rate_filter(cmd64x_ratemask(drive), speed); 302 speed = ide_rate_filter(drive, speed);
352 303
353 if (speed >= XFER_SW_DMA_0) { 304 if (speed >= XFER_SW_DMA_0) {
354 (void) pci_read_config_byte(dev, pciU, &regU); 305 (void) pci_read_config_byte(dev, pciU, &regU);
@@ -403,7 +354,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed)
403 354
404static int config_chipset_for_dma (ide_drive_t *drive) 355static int config_chipset_for_dma (ide_drive_t *drive)
405{ 356{
406 u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive)); 357 u8 speed = ide_max_dma_mode(drive);
407 358
408 if (!speed) 359 if (!speed)
409 return 0; 360 return 0;
@@ -646,6 +597,18 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
646 597
647 hwif->ultra_mask = hwif->cds->udma_mask; 598 hwif->ultra_mask = hwif->cds->udma_mask;
648 599
600 /*
601 * UltraDMA only supported on PCI646U and PCI646U2, which
602 * correspond to revisions 0x03, 0x05 and 0x07 respectively.
603 * Actually, although the CMD tech support people won't
604 * tell me the details, the 0x03 revision cannot support
605 * UDMA correctly without hardware modifications, and even
606 * then it only works with Quantum disks due to some
607 * hold time assumptions in the 646U part which are fixed
608 * in the 646U2.
609 *
610 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
611 */
649 if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5) 612 if (dev->device == PCI_DEVICE_ID_CMD_646 && class_rev < 5)
650 hwif->ultra_mask = 0x00; 613 hwif->ultra_mask = 0x00;
651 614