(pata-2.6 fix queue) sl82c105: DMA support code cleanup
PATCH 1/1 (pata-2.6 fix queue) sl82c105: DMA support code cleanup
Fold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods.
---
The patch has been actually tested at last. :-)
Note that now this driver can be joined to the ide-use-fast-pio patch.
drivers/ide/pci/sl82c105.c | 114 +++++++++++++++++---------------------------- 1 files changed, 45 insertions(+), 69 deletions(-)
drivers/ide/pci/sl82c105.c +45 -69
@@ -11,6 +11,8 @@* Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) [email protected] +* +* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]> */ #include <linux/types.h>
@@ -114,59 +116,32 @@ static void config_for_pio(ide_drive_t * }/* -* Configure the drive and the chipset for DMA +* Configure the drive for DMA. +* We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; -unsigned int reg; -DBG (("config_for_dma(drive:%s)\n" , drive->name)); - reg = (hwif->channel ?0x4c :0x44 ) + (drive->select.b.unit ?4 :0 ); -if (ide_config_drive_speed (drive,XFER_MW_DMA_2 ) !=0 ) -return 1 ; +return 0 ; -pci_write_config_word (dev, reg,0x0240 ); - -return 0 ; +return ide_dma_enable (drive); }/* -* Check to see if the drive and -* chipset is capable of DMA mode +* Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) {ide_hwif_t *hwif =HWIF (drive); +struct hd_driveid *id = drive->id; -DBG (("sl82c105_check_drive(drive:%s)\n" , drive->name)); - -do { -struct hd_driveid *id = drive->id; - -if (!drive->autodma) -break ; - -if (!id || !(id->capability &1 )) -break ; - -/* Consult the list of known "bad" drives */ -if (__ide_dma_bad_drive (drive)) -break ; +DBG (("sl82c105_ide_dma_check(drive:%s)\n" , drive->name)); -if (id->field_valid &2 ) { -if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) -return hwif->ide_dma_on (drive); - } - -if (__ide_dma_good_drive (drive) && id->eide_dma_time <150 ) -return hwif->ide_dma_on (drive); - }while (0 ); +if (drive->autodma && (id->capability &1 ) && +ide_use_dma (drive) &&config_for_dma (drive)) +return hwif->ide_dma_on (drive);return hwif->ide_dma_off_quietly (drive); }
@@ -235,7 +210,7 @@ static int sl82c105_ide_dma_lost_irq(ide* The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start (ide_drive_t *drive) +static void sl82c105_dma_start (ide_drive_t *drive) {ide_hwif_t *hwif =HWIF (drive);struct pci_dev *dev = hwif->pci_dev;
@@ -257,12 +232,18 @@ static int sl82c105_ide_dma_timeout(ide_static int sl82c105_ide_dma_on (ide_drive_t *drive) { +struct pci_dev *dev =HWIF (drive)->pci_dev; +int rc, reg =0x44 + drive->dn *4 ; +DBG (("sl82c105_ide_dma_on(drive:%s)\n" , drive->name)); -if (config_for_dma (drive)) -return 1 ; -printk (KERN_INFO "%s: DMA enabled\n" , drive->name); -return __ide_dma_on (drive); + rc =__ide_dma_on (drive); +if (rc ==0 ) { +pci_write_config_word (dev, reg,0x0200 ); + +printk (KERN_INFO "%s: DMA enabled\n" , drive->name); + } +return rc; }static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
@@ -396,7 +377,7 @@ static unsigned int __devinit init_chips }/* -* Initialise the chip +* Initialise IDE channel */ static void __devinit init_hwif_sl82c105 (ide_hwif_t *hwif) {
@@ -418,11 +399,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[1 ].pio_speed =XFER_PIO_0 ; hwif->drives[1 ].autotune =1 ; - hwif->atapi_dma =0 ; - hwif->mwdma_mask =0 ; - hwif->swdma_mask =0 ; - hwif->autodma =0 ; -if (!hwif->dma_base)return ;
@@ -432,27 +408,27 @@ static void __devinit init_hwif_sl82c105* Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ -printk (" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n" , - hwif->name, rev); - }else { - hwif->atapi_dma =1 ; - hwif->mwdma_mask =0x04 ; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - -if (!noautodma) - hwif->autodma =1 ; - hwif->drives[0 ].autodma = hwif->autodma; - hwif->drives[1 ].autodma = hwif->autodma; - -if (hwif->mate) - hwif->serialized = hwif->mate->serialized =1 ; +printk (" %s: Winbond W83C553 bridge revision %d, " +"BM-DMA disabled\n" , hwif->name, rev); +return ; } + + hwif->atapi_dma =1 ; + hwif->mwdma_mask =0x04 ; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + +if (!noautodma) + hwif->autodma =1 ; + hwif->drives[0 ].autodma = hwif->drives[1 ].autodma = hwif->autodma; + +if (hwif->mate) + hwif->serialized = hwif->mate->serialized =1 ; }static ide_pci_device_t sl82c105_chipset__devinitdata = {
Bartlomiej Zolnierkiewicz
AppliedQuoted 8 lines · Sergei Shtylyov
Fold the now equivalent code in the
ide_dma_check()method into a mere call toide_use_dma(). Makeconfig_for_dma()return non-zero if DMA mode has been set and call it from theide_dma_check()method instead ofide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from theinit_hwif()method, improve its looks overall, and also rename the driver'side_dma_check()anddma_start()methods.
Quoted 5 lines
Signed-off-by Sergei Shtylyov <[email protected]>---
The patch has been actually tested at last. :-)
Note that now this driver can be joined to the ide-use-fast-pio patch.
applied
PATCH 1/1 (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 2)
In reply to Sergei ShtylyovFold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods.
---
This version takes into account that the ide-use-fast-pio.patch had been merged to mainline...
drivers/ide/pci/sl82c105.c | 112 ++++++++++++++++----------------------------- 1 files changed, 41 insertions(+), 71 deletions(-)
drivers/ide/pci/sl82c105.c +43 -71
@@ -11,6 +11,8 @@* Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) [email protected] +* +* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]> */ #include <linux/types.h>
@@ -115,59 +117,28 @@ static void sl82c105_tune_drive(ide_driv }/* -* Configure the drive and the chipset for DMA ++ * Configure the drive for DMA. ++ * We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; -unsigned int reg; -DBG (("config_for_dma(drive:%s)\n" , drive->name)); - reg = (hwif->channel ?0x4c :0x44 ) + (drive->select.b.unit ?4 :0 ); -if (ide_config_drive_speed (drive,XFER_MW_DMA_2 ) !=0 ) -return 1 ; - -pci_write_config_word (dev, reg,0x0240 ); +return 0 ; -return 0 ; +return ide_dma_enable (drive); }/* -* Check to see if the drive and -* chipset is capable of DMA mode +* Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); - -DBG (("sl82c105_check_drive(drive:%s)\n" , drive->name)); - -do { -struct hd_driveid *id = drive->id; - -if (!drive->autodma) -break ; +DBG (("sl82c105_ide_dma_check(drive:%s)\n" , drive->name)); -if (!id || !(id->capability &1 )) -break ; - -/* Consult the list of known "bad" drives */ -if (__ide_dma_bad_drive (drive)) -break ; - -if (id->field_valid &2 ) { -if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) -return 0 ; - } - -if (__ide_dma_good_drive (drive) && id->eide_dma_time <150 ) -return 0 ; - }while (0 ); +if (ide_use_dma (drive) &&config_for_dma (drive)) +return 0 ;return -1 ; }
@@ -236,7 +207,7 @@ static int sl82c105_ide_dma_lost_irq(ide* The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start (ide_drive_t *drive) +static void sl82c105_dma_start (ide_drive_t *drive) {ide_hwif_t *hwif =HWIF (drive);struct pci_dev *dev = hwif->pci_dev;
@@ -258,12 +229,18 @@ static int sl82c105_ide_dma_timeout(ide_static int sl82c105_ide_dma_on (ide_drive_t *drive) { +struct pci_dev *dev =HWIF (drive)->pci_dev; +int rc, reg =0x44 + drive->dn *4 ; +DBG (("sl82c105_ide_dma_on(drive:%s)\n" , drive->name)); -if (config_for_dma (drive)) -return 1 ; -printk (KERN_INFO "%s: DMA enabled\n" , drive->name); -return __ide_dma_on (drive); + rc =__ide_dma_on (drive); +if (rc ==0 ) { +pci_write_config_word (dev, reg,0x0200 ); + +printk (KERN_INFO "%s: DMA enabled\n" , drive->name); + } +return rc; }static void sl82c105_dma_off_quietly (ide_drive_t *drive)
@@ -376,7 +353,7 @@ static unsigned int __devinit init_chips }/* -* Initialise the chip +* Initialise IDE channel */ static void __devinit init_hwif_sl82c105 (ide_hwif_t *hwif) {
@@ -396,11 +373,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[0 ].drive_data = hwif->drives[1 ].drive_data =0x0909 ; hwif->drives[0 ].autotune = hwif->drives[1 ].autotune =1 ; - hwif->atapi_dma =0 ; - hwif->mwdma_mask =0 ; - hwif->swdma_mask =0 ; - hwif->autodma =0 ; -if (!hwif->dma_base)return ;
@@ -410,27 +382,27 @@ static void __devinit init_hwif_sl82c105* Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ -printk (" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n" , - hwif->name, rev); - }else { - hwif->atapi_dma =1 ; - hwif->mwdma_mask =0x04 ; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - -if (!noautodma) - hwif->autodma =1 ; - hwif->drives[0 ].autodma = hwif->autodma; - hwif->drives[1 ].autodma = hwif->autodma; - -if (hwif->mate) - hwif->serialized = hwif->mate->serialized =1 ; +printk (" %s: Winbond W83C553 bridge revision %d, " +"BM-DMA disabled\n" , hwif->name, rev); +return ; } + + hwif->atapi_dma =1 ; + hwif->mwdma_mask =0x04 ; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + +if (!noautodma) + hwif->autodma =1 ; + hwif->drives[0 ].autodma = hwif->drives[1 ].autodma = hwif->autodma; + +if (hwif->mate) + hwif->serialized = hwif->mate->serialized =1 ; }static ide_pci_device_t sl82c105_chipset__devinitdata = {
PATCH 1/1 (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3)
In reply to Sergei ShtylyovFold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from the init_hwif() method, improve its looks overall, and also rename the driver's ide_dma_check() and dma_start() methods.
---
This version takes into account that the ide-use-fast-pio.patch had been merged to mainline...
Argh! Where those extra pluses camen from in the second hunk?!
drivers/ide/pci/sl82c105.c | 112 ++++++++++++++++----------------------------- 1 files changed, 41 insertions(+), 71 deletions(-)
drivers/ide/pci/sl82c105.c +43 -71
@@ -11,6 +11,8 @@* Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) [email protected] +* +* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]> */ #include <linux/types.h>
@@ -115,59 +117,28 @@ static void sl82c105_tune_drive(ide_driv }/* -* Configure the drive and the chipset for DMA +* Configure the drive for DMA. +* We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; -unsigned int reg; -DBG (("config_for_dma(drive:%s)\n" , drive->name)); - reg = (hwif->channel ?0x4c :0x44 ) + (drive->select.b.unit ?4 :0 ); -if (ide_config_drive_speed (drive,XFER_MW_DMA_2 ) !=0 ) -return 1 ; - -pci_write_config_word (dev, reg,0x0240 ); +return 0 ; -return 0 ; +return ide_dma_enable (drive); }/* -* Check to see if the drive and -* chipset is capable of DMA mode +* Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); - -DBG (("sl82c105_check_drive(drive:%s)\n" , drive->name)); - -do { -struct hd_driveid *id = drive->id; - -if (!drive->autodma) -break ; +DBG (("sl82c105_ide_dma_check(drive:%s)\n" , drive->name)); -if (!id || !(id->capability &1 )) -break ; - -/* Consult the list of known "bad" drives */ -if (__ide_dma_bad_drive (drive)) -break ; - -if (id->field_valid &2 ) { -if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) -return 0 ; - } - -if (__ide_dma_good_drive (drive) && id->eide_dma_time <150 ) -return 0 ; - }while (0 ); +if (ide_use_dma (drive) &&config_for_dma (drive)) +return 0 ;return -1 ; }
@@ -236,7 +207,7 @@ static int sl82c105_ide_dma_lost_irq(ide* The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start (ide_drive_t *drive) +static void sl82c105_dma_start (ide_drive_t *drive) {ide_hwif_t *hwif =HWIF (drive);struct pci_dev *dev = hwif->pci_dev;
@@ -258,12 +229,18 @@ static int sl82c105_ide_dma_timeout(ide_static int sl82c105_ide_dma_on (ide_drive_t *drive) { +struct pci_dev *dev =HWIF (drive)->pci_dev; +int rc, reg =0x44 + drive->dn *4 ; +DBG (("sl82c105_ide_dma_on(drive:%s)\n" , drive->name)); -if (config_for_dma (drive)) -return 1 ; -printk (KERN_INFO "%s: DMA enabled\n" , drive->name); -return __ide_dma_on (drive); + rc =__ide_dma_on (drive); +if (rc ==0 ) { +pci_write_config_word (dev, reg,0x0200 ); + +printk (KERN_INFO "%s: DMA enabled\n" , drive->name); + } +return rc; }static void sl82c105_dma_off_quietly (ide_drive_t *drive)
@@ -376,7 +353,7 @@ static unsigned int __devinit init_chips }/* -* Initialise the chip +* Initialise IDE channel */ static void __devinit init_hwif_sl82c105 (ide_hwif_t *hwif) {
@@ -396,11 +373,6 @@ static void __devinit init_hwif_sl82c105 hwif->drives[0 ].drive_data = hwif->drives[1 ].drive_data =0x0909 ; hwif->drives[0 ].autotune = hwif->drives[1 ].autotune =1 ; - hwif->atapi_dma =0 ; - hwif->mwdma_mask =0 ; - hwif->swdma_mask =0 ; - hwif->autodma =0 ; -if (!hwif->dma_base)return ;
@@ -410,27 +382,27 @@ static void __devinit init_hwif_sl82c105* Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ -printk (" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n" , - hwif->name, rev); - }else { - hwif->atapi_dma =1 ; - hwif->mwdma_mask =0x04 ; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - -if (!noautodma) - hwif->autodma =1 ; - hwif->drives[0 ].autodma = hwif->autodma; - hwif->drives[1 ].autodma = hwif->autodma; - -if (hwif->mate) - hwif->serialized = hwif->mate->serialized =1 ; +printk (" %s: Winbond W83C553 bridge revision %d, " +"BM-DMA disabled\n" , hwif->name, rev); +return ; } + + hwif->atapi_dma =1 ; + hwif->mwdma_mask =0x04 ; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + +if (!noautodma) + hwif->autodma =1 ; + hwif->drives[0 ].autodma = hwif->drives[1 ].autodma = hwif->autodma; + +if (hwif->mate) + hwif->serialized = hwif->mate->serialized =1 ; }static ide_pci_device_t sl82c105_chipset__devinitdata = {
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH] (pata-2.6 fix queue) sl82c105: DMA support code cleanup (take 3)
Quoted 11 lines · Sergei Shtylyov
Fold the now equivalent code in the
ide_dma_check()method into a mere call toide_use_dma(). Makeconfig_for_dma()return non-zero if DMA mode has been set and call it from theide_dma_check()method instead ofide_dma_on(). Also, defer writing the DMA timings to the chip registers until DMA is actually turned on (and do not enable IORDY for DMA). Remove unnecessary code from theinit_hwif()method, improve its looks overall, and also rename the driver'side_dma_check()anddma_start()methods.---
This version takes into account that the ide-use-fast-pio.patch had been merged to mainline...
applied
PATCH 1/1 sl82c105: DMA support code cleanup (take 4)
In reply to Sergei ShtylyovFold the now equivalent code in the ide_dma_check() method into a mere call to ide_use_dma(). Make config_for_dma() return non-zero if DMA mode has been set and call it from the ide_dma_check() method instead of ide_dma_on(). Defer writing the DMA timings to the chip registers until DMA is really turned on (and do not enable IORDY for DMA).
Remove unneeded code from the init_hwif() method, improve its overall looks. Rename the dma_start(), ide_dma_check(), and ide_dma_lostirq() methods, and also use more proper hwif->dma_command, fix printk() and comment in the latter one as well. While at it, cleanup style in several places.
---
This patch has also been actually tested at last. :-)
drivers/ide/pci/sl82c105.c | 148 +++++++++++++++++---------------------------- 1 files changed, 59 insertions(+), 89 deletions(-)
drivers/ide/pci/sl82c105.c +59 -89
@@ -100,59 +100,28 @@ static u8 sl82c105_tune_pio(ide_drive_t }/* -* Configure the drive and the chipset for DMA +* Configure the drive for DMA. +* We'll program the chipset only when DMA is actually turned on. */ -static int config_for_dma (ide_drive_t *drive) +static int config_for_dma (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; -unsigned int reg; -DBG (("config_for_dma(drive:%s)\n" , drive->name)); - reg = (hwif->channel ?0x4c :0x44 ) + (drive->select.b.unit ?4 :0 ); -if (ide_config_drive_speed (drive,XFER_MW_DMA_2 ) !=0 ) -return 1 ; - -pci_write_config_word (dev, reg,0x0240 ); +return 0 ; -return 0 ; +return ide_dma_enable (drive); }/* -* Check to see if the drive and -* chipset is capable of DMA mode +* Check to see if the drive and chipset are capable of DMA mode. */ - -static int sl82c105_check_drive (ide_drive_t *drive) +static int sl82c105_ide_dma_check (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); - -DBG (("sl82c105_check_drive(drive:%s)\n" , drive->name)); +DBG (("sl82c105_ide_dma_check(drive:%s)\n" , drive->name)); -do { -struct hd_driveid *id = drive->id; - -if (!drive->autodma) -break ; - -if (!id || !(id->capability &1 )) -break ; - -/* Consult the list of known "bad" drives */ -if (__ide_dma_bad_drive (drive)) -break ; - -if (id->field_valid &2 ) { -if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) -return 0 ; - } - -if (__ide_dma_good_drive (drive) && id->eide_dma_time <150 ) -return 0 ; - }while (0 ); +if (ide_use_dma (drive) &&config_for_dma (drive)) +return 0 ;return -1 ; }
@@ -181,14 +150,14 @@ static inline void sl82c105_reset_host(s* This function is called when the IDE timer expires, the drive * indicates that it is READY, and we were waiting for DMA to complete. */ -static int sl82c105_ide_dma_lost_irq (ide_drive_t *drive) +static int sl82c105_ide_dma_lostirq (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; -u32 val, mask = hwif->channel ?CTRL_IDE_IRQB :CTRL_IDE_IRQA ; -unsigned long dma_base = hwif->dma_base; +ide_hwif_t *hwif =HWIF (drive); +struct pci_dev *dev = hwif->pci_dev; +u32 val, mask = hwif->channel ?CTRL_IDE_IRQB :CTRL_IDE_IRQA ; +u8 dma_cmd; -printk ("sl82c105: lost IRQ: resetting host\n" ); +printk ("sl82c105: lost IRQ, resetting host\n" );/* * Check the raw interrupt from the drive.
@@ -201,15 +170,15 @@ static int sl82c105_ide_dma_lost_irq(ide* Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - val =inb (dma_base); -if (val &1 ) { -outb (val & ~1 , dma_base); + dma_cmd =inb (hwif->dma_command); +if (dma_cmd &1 ) { +outb (dma_cmd & ~1 , hwif->dma_command);printk ("sl82c105: DMA was enabled\n" ); }sl82c105_reset_host (dev); -/* ide_dmaproc would return 1, so we do as well */ +/* __ide_dma_lostirq would return 1, so we do as well */ return 1 ; }
@@ -221,10 +190,10 @@ static int sl82c105_ide_dma_lost_irq(ide* The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_ide_dma_start (ide_drive_t *drive) +static void sl82c105_dma_start (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; +ide_hwif_t *hwif =HWIF (drive); +struct pci_dev *dev = hwif->pci_dev;sl82c105_reset_host (dev);ide_dma_start (drive);
@@ -232,8 +201,8 @@ static void sl82c105_ide_dma_start(ide_dstatic int sl82c105_ide_dma_timeout (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; +ide_hwif_t *hwif =HWIF (drive); +struct pci_dev *dev = hwif->pci_dev;DBG (("sl82c105_ide_dma_timeout(drive:%s)\n" , drive->name));
@@ -241,14 +210,20 @@ static int sl82c105_ide_dma_timeout(ide_return __ide_dma_timeout (drive); } -static int sl82c105_ide_dma_on (ide_drive_t *drive) +static int sl82c105_ide_dma_on (ide_drive_t *drive) { +struct pci_dev *dev =HWIF (drive)->pci_dev; +int rc, reg =0x44 + drive->dn *4 ; +DBG (("sl82c105_ide_dma_on(drive:%s)\n" , drive->name)); -if (config_for_dma (drive)) -return 1 ; -printk (KERN_INFO "%s: DMA enabled\n" , drive->name); -return __ide_dma_on (drive); + rc =__ide_dma_on (drive); +if (rc ==0 ) { +pci_write_config_word (dev, reg,0x0200 ); + +printk (KERN_INFO "%s: DMA enabled\n" , drive->name); + } +return rc; }static void sl82c105_dma_off_quietly (ide_drive_t *drive)
@@ -272,8 +247,8 @@ static void sl82c105_dma_off_quietly(ide*/ static void sl82c105_selectproc (ide_drive_t *drive) { -ide_hwif_t *hwif =HWIF (drive); -struct pci_dev *dev = hwif->pci_dev; +ide_hwif_t *hwif =HWIF (drive); +struct pci_dev *dev = hwif->pci_dev;u32 val, old, mask;//DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
@@ -373,7 +348,7 @@ static unsigned int __devinit init_chips }/* -* Initialise the chip +* Initialise IDE channel */ static void __devinit init_hwif_sl82c105 (ide_hwif_t *hwif) {
@@ -398,11 +373,6 @@ static void __devinit init_hwif_sl82c105*/ hwif->drives[0 ].autotune = hwif->drives[1 ].autotune =1 ; - hwif->atapi_dma =0 ; - hwif->mwdma_mask =0 ; - hwif->swdma_mask =0 ; - hwif->autodma =0 ; -if (!hwif->dma_base)return ;
@@ -412,27 +382,27 @@ static void __devinit init_hwif_sl82c105* Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ -printk (" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n" , - hwif->name, rev); - }else { - hwif->atapi_dma =1 ; - hwif->mwdma_mask =0x04 ; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - -if (!noautodma) - hwif->autodma =1 ; - hwif->drives[0 ].autodma = hwif->autodma; - hwif->drives[1 ].autodma = hwif->autodma; - -if (hwif->mate) - hwif->serialized = hwif->mate->serialized =1 ; +printk (" %s: Winbond W83C553 bridge revision %d, " +"BM-DMA disabled\n" , hwif->name, rev); +return ; } + + hwif->atapi_dma =1 ; + hwif->mwdma_mask =0x04 ; + + hwif->ide_dma_check = &sl82c105_ide_dma_check; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; + hwif->dma_start = &sl82c105_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + +if (!noautodma) + hwif->autodma =1 ; + hwif->drives[0 ].autodma = hwif->drives[1 ].autodma = hwif->autodma; + +if (hwif->mate) + hwif->serialized = hwif->mate->serialized =1 ; }static ide_pci_device_t sl82c105_chipset__devinitdata = {
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH pata-2.6] sl82c105: DMA support code cleanup (take 4)
Quoted 10 lines · Sergei Shtylyov
Fold the now equivalent code in the
ide_dma_check()method into a mere call toide_use_dma(). Makeconfig_for_dma()return non-zero if DMA mode has been set and call it from theide_dma_check()method instead ofide_dma_on(). Defer writing the DMA timings to the chip registers until DMA is really turned on (and do not enable IORDY for DMA).
Remove unneeded code from theinit_hwif()method, improve its overall looks. Rename thedma_start(),ide_dma_check(), andide_dma_lostirq()methods, and also use more properhwif->dma_command, fixprintk()and comment in the latter one as well. While at it, cleanup style in several places.
Quoted 5 lines
---
This patch has also been actually tested at last. :-)Signed-off-by Sergei Shtylyov <[email protected]>Signed-off-by Bartlomiej Zolnierkiewicz <[email protected]>
I moved Signed-off-by-s before "---" to prevent them from being eaten by git.
applied
PATCH 1/1 sl82c105: add speedproc() method and MWDMA0/1 support
In reply to Sergei ShtylyovAdd the speedproc() method for setting transfer modes, modify config_for_dma() to call it and use ide_max_dma_mode() to select the best DMA mode. Add support for the multiword DMA modes 0 and 1, using the upper half of the 'drive_data' field to store the DMA timings to program into the drive control register when DMA is turned on for real.
---
This patch replaces sl82c105-add-speedproc.patch from pata-2.6 patchset.
drivers/ide/pci/sl82c105.c | 71 +++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 66 insertions(+), 5 deletions(-)
drivers/ide/pci/sl82c105.c +66 -5
@@ -82,7 +82,14 @@ static u8 sl82c105_tune_pio(ide_drive_t pio =ide_get_best_pio_mode (drive, pio,5 , &p); - drive->drive_data = drv_ctrl =get_pio_timings (&p); + drv_ctrl =get_pio_timings (&p); + +/* +* Store the PIO timings so that we can restore them +* in case DMA will be turned off... +*/ + drive->drive_data &=0xffff0000 ; + drive->drive_data |= drv_ctrl;if (!drive->using_dma) {/*
@@ -100,14 +107,67 @@ static u8 sl82c105_tune_pio(ide_drive_t }/* +* Configure the drive and chipset for a new transfer speed. +*/ +static int sl82c105_tune_chipset (ide_drive_t *drive,u8 speed) +{ +static u16 mwdma_timings[] = {0x0707 ,0x0201 ,0x0200 }; +u16 drv_ctrl; + +DBG (("sl82c105_tune_chipset(drive:%s, speed:%s)\n" , + drive->name,ide_xfer_verbose (speed))); + + speed =ide_rate_filter (drive, speed); + +switch (speed) { +case XFER_MW_DMA_2 : +case XFER_MW_DMA_1 : +case XFER_MW_DMA_0 : + drv_ctrl = mwdma_timings[speed -XFER_MW_DMA_0 ]; + +/* +* Store the DMA timings so that we can actually program +* them when DMA will be turned on... +*/ + drive->drive_data &=0x0000ffff ; + drive->drive_data |= (unsigned long )drv_ctrl <<16 ; + +/* +* If we are already using DMA, we just reprogram +* the drive control register. +*/ +if (drive->using_dma) { +struct pci_dev *dev =HWIF (drive)->pci_dev; +int reg =0x44 + drive->dn *4 ; + +pci_write_config_word (dev, reg, drv_ctrl); + } +break ; +case XFER_PIO_5 : +case XFER_PIO_4 : +case XFER_PIO_3 : +case XFER_PIO_2 : +case XFER_PIO_1 : +case XFER_PIO_0 : + (void )sl82c105_tune_pio (drive, speed -XFER_PIO_0 ); +break ; +default : +return -1 ; + } + +return ide_config_drive_speed (drive, speed); +} + +/* * Configure the drive for DMA. -* We'll program the chipset only when DMA is actually turned on. */ static int config_for_dma (ide_drive_t *drive) { +u8 speed =ide_max_dma_mode (drive); +DBG (("config_for_dma(drive:%s)\n" , drive->name)); -if (ide_config_drive_speed (drive,XFER_MW_DMA_2 ) !=0 ) +if (!speed ||sl82c105_tune_chipset (drive, speed))return 0 ;return ide_dma_enable (drive);
@@ -219,7 +279,7 @@ static int sl82c105_ide_dma_on(ide_drive rc =__ide_dma_on (drive);if (rc ==0 ) { -pci_write_config_word (dev, reg,0x0200 ); +pci_write_config_word (dev, reg, drive->drive_data >>16 );printk (KERN_INFO "%s: DMA enabled\n" , drive->name); }
@@ -357,6 +417,7 @@ static void __devinit init_hwif_sl82c105DBG (("init_hwif_sl82c105(hwif: ide%d)\n" , hwif->index)); hwif->tuneproc = &sl82c105_tune_drive; + hwif->speedproc = &sl82c105_tune_chipset; hwif->selectproc = &sl82c105_selectproc; hwif->resetproc = &sl82c105_resetproc;
@@ -388,7 +449,7 @@ static void __devinit init_hwif_sl82c105 } hwif->atapi_dma =1 ; - hwif->mwdma_mask =0x04 ; + hwif->mwdma_mask =0x07 ; hwif->ide_dma_check = &sl82c105_ide_dma_check; hwif->ide_dma_on = &sl82c105_ide_dma_on;
Bartlomiej Zolnierkiewicz
AppliedRe: [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support
Quoted 7 lines · Sergei Shtylyov
Add the
speedproc()method for setting transfer modes, modifyconfig_for_dma()to call it and useide_max_dma_mode()to select the best DMA mode. Add support for the multiword DMA modes 0 and 1, using the upper half of the 'drive_data' field to store the DMA timings to program into the drive control register when DMA is turned on for real.Signed-off-by Sergei Shtylyov <[email protected]>
applied
Re: [PATCH pata-2.6] sl82c105: add speedproc() method and MWDMA0/1 support
Hello.
Quoted 9 lines · Bartlomiej Zolnierkiewicz
Quoted 7 lines
Add the
speedproc()method for setting transfer modes, modifyconfig_for_dma()to call it and useide_max_dma_mode()to select the best DMA mode. Add support for the multiword DMA modes 0 and 1, using the upper half of the 'drive_data' field to store the DMA timings to program into the drive control register when DMA is turned on for real.Signed-off-by Sergei Shtylyov <[email protected]>applied
I now also have almost complete patch to merge PIO/DMA timings and so get
rid of selectproc() there... :-)
MBR, Sergei