cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
/*
2005-04-17 02:20:36 +04:00
* cmd64x . c : Enable interrupts at initialization time on Ultra / PCI machines .
* Due to massive hardware bugs , UltraDMA is only supported
* on the 646U 2 and not on the 646U .
*
* Copyright ( C ) 1998 Eddie C . Dost ( ecd @ skynet . be )
* Copyright ( C ) 1998 David S . Miller ( davem @ redhat . com )
*
* Copyright ( C ) 1999 - 2002 Andre Hedrick < andre @ linux - ide . org >
2010-01-18 10:18:26 +03:00
* Copyright ( C ) 2007 - 2010 Bartlomiej Zolnierkiewicz
2009-06-15 20:52:56 +04:00
* Copyright ( C ) 2007 , 2009 MontaVista Software , Inc . < source @ mvista . com >
2005-04-17 02:20:36 +04:00
*/
# include <linux/module.h>
# include <linux/types.h>
# include <linux/pci.h>
# include <linux/ide.h>
# include <linux/init.h>
# include <asm/io.h>
2008-07-25 00:53:32 +04:00
# define DRV_NAME "cmd64x"
2005-04-17 02:20:36 +04:00
/*
* CMD64x specific registers definition .
*/
# define CFR 0x50
2007-05-06 00:03:49 +04:00
# define CFR_INTR_CH0 0x04
2005-04-17 02:20:36 +04:00
# define CMDTIM 0x52
# define ARTTIM0 0x53
# define DRWTIM0 0x54
# define ARTTIM1 0x55
# define DRWTIM1 0x56
# define ARTTIM23 0x57
# define ARTTIM23_DIS_RA2 0x04
# define ARTTIM23_DIS_RA3 0x08
# define ARTTIM23_INTR_CH1 0x10
# define DRWTIM2 0x58
# define BRST 0x59
# define DRWTIM3 0x5b
# define BMIDECR0 0x70
# define MRDMODE 0x71
# define MRDMODE_INTR_CH0 0x04
# define MRDMODE_INTR_CH1 0x08
# define UDIDETCR0 0x73
# define DTPR0 0x74
# define BMIDECR1 0x78
# define BMIDECSR 0x79
# define UDIDETCR1 0x7B
# define DTPR1 0x7C
2010-01-18 10:18:26 +03:00
static void cmd64x_program_timings ( ide_drive_t * drive , u8 mode )
2005-04-17 02:20:36 +04:00
{
2010-01-18 10:18:26 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2008-04-27 17:38:29 +04:00
struct pci_dev * dev = to_pci_dev ( drive - > hwif - > dev ) ;
2010-01-18 10:18:26 +03:00
int bus_speed = ide_pci_clk ? ide_pci_clk : 33 ;
const unsigned long T = 1000000 / bus_speed ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
static const u8 recovery_values [ ] =
2005-04-17 02:20:36 +04:00
{ 15 , 15 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 0 } ;
2010-01-18 10:18:26 +03:00
static const u8 setup_values [ ] = { 0x40 , 0x40 , 0x40 , 0x80 , 0 , 0xc0 } ;
static const u8 arttim_regs [ 4 ] = { ARTTIM0 , ARTTIM1 , ARTTIM23 , ARTTIM23 } ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
static const u8 drwtim_regs [ 4 ] = { DRWTIM0 , DRWTIM1 , DRWTIM2 , DRWTIM3 } ;
2010-01-18 10:18:26 +03:00
struct ide_timing t ;
u8 arttim = 0 ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
2010-01-18 10:18:26 +03:00
ide_timing_compute ( drive , mode , & t , T , 0 ) ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
2005-04-17 02:20:36 +04:00
/*
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
* In case we ' ve got too long recovery phase , try to lengthen
* the active phase
2005-04-17 02:20:36 +04:00
*/
2010-01-18 10:18:26 +03:00
if ( t . recover > 16 ) {
t . active + = t . recover - 16 ;
t . recover = 16 ;
2005-04-17 02:20:36 +04:00
}
2010-01-18 10:18:26 +03:00
if ( t . active > 16 ) /* shouldn't actually happen... */
t . active = 16 ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
2005-04-17 02:20:36 +04:00
/*
* Convert values to internal chipset representation
*/
2010-01-18 10:18:26 +03:00
t . recover = recovery_values [ t . recover ] ;
t . active & = 0x0f ;
2005-04-17 02:20:36 +04:00
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
/* Program the active/recovery counts into the DRWTIM register */
2010-01-18 10:18:26 +03:00
pci_write_config_byte ( dev , drwtim_regs [ drive - > dn ] ,
( t . active < < 4 ) | t . recover ) ;
2005-04-17 02:20:36 +04:00
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
/*
* The primary channel has individual address setup timing registers
* for each drive and the hardware selects the slowest timing itself .
* The secondary channel has one common register and we have to select
* the slowest address setup timing ourselves .
*/
if ( hwif - > channel ) {
2009-01-06 19:20:55 +03:00
ide_drive_t * pair = ide_get_pair_dev ( drive ) ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
2010-01-18 10:21:41 +03:00
if ( pair ) {
struct ide_timing tp ;
ide_timing_compute ( pair , pair - > pio_mode , & tp , T , 0 ) ;
ide_timing_merge ( & t , & tp , & t , IDE_TIMING_SETUP ) ;
if ( pair - > dma_mode ) {
ide_timing_compute ( pair , pair - > dma_mode ,
& tp , T , 0 ) ;
ide_timing_merge ( & tp , & t , & t , IDE_TIMING_SETUP ) ;
}
}
2005-04-17 02:20:36 +04:00
}
2010-01-18 10:18:26 +03:00
if ( t . setup > 5 ) /* shouldn't actually happen... */
t . setup = 5 ;
2005-04-17 02:20:36 +04:00
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
/*
* Program the address setup clocks into the ARTTIM registers .
* Avoid clearing the secondary channel ' s interrupt bit .
*/
( void ) pci_read_config_byte ( dev , arttim_regs [ drive - > dn ] , & arttim ) ;
if ( hwif - > channel )
arttim & = ~ ARTTIM23_INTR_CH1 ;
arttim & = ~ 0xc0 ;
2010-01-18 10:18:26 +03:00
arttim | = setup_values [ t . setup ] ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
( void ) pci_write_config_byte ( dev , arttim_regs [ drive - > dn ] , arttim ) ;
2007-03-03 19:48:53 +03:00
}
/*
* Attempts to set drive ' s PIO mode .
2007-10-12 01:54:00 +04:00
* Special cases are 8 : prefetch off , 9 : prefetch on ( both never worked )
2007-03-03 19:48:53 +03:00
*/
2007-10-12 01:54:00 +04:00
2010-01-19 12:44:41 +03:00
static void cmd64x_set_pio_mode ( ide_hwif_t * hwif , ide_drive_t * drive )
2007-03-03 19:48:53 +03:00
{
2010-01-19 12:44:41 +03:00
const u8 pio = drive - > pio_mode - XFER_PIO_0 ;
2007-03-03 19:48:53 +03:00
/*
* Filter out the prefetch control values
* to prevent PIO5 from being programmed
*/
if ( pio = = 8 | | pio = = 9 )
return ;
2010-01-18 10:18:26 +03:00
cmd64x_program_timings ( drive , XFER_PIO_0 + pio ) ;
2005-04-17 02:20:36 +04:00
}
2010-01-19 12:45:29 +03:00
static void cmd64x_set_dma_mode ( ide_hwif_t * hwif , ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2008-02-02 01:09:31 +03:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
u8 unit = drive - > dn & 0x01 ;
u8 regU = 0 , pciU = hwif - > channel ? UDIDETCR1 : UDIDETCR0 ;
2010-01-19 12:45:29 +03:00
const u8 speed = drive - > dma_mode ;
2005-04-17 02:20:36 +04:00
2010-01-18 10:18:38 +03:00
pci_read_config_byte ( dev , pciU , & regU ) ;
regU & = ~ ( unit ? 0xCA : 0x35 ) ;
2005-04-17 02:20:36 +04:00
switch ( speed ) {
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
case XFER_UDMA_5 :
regU | = unit ? 0x0A : 0x05 ;
break ;
case XFER_UDMA_4 :
regU | = unit ? 0x4A : 0x15 ;
break ;
case XFER_UDMA_3 :
regU | = unit ? 0x8A : 0x25 ;
break ;
case XFER_UDMA_2 :
regU | = unit ? 0x42 : 0x11 ;
break ;
case XFER_UDMA_1 :
regU | = unit ? 0x82 : 0x21 ;
break ;
case XFER_UDMA_0 :
regU | = unit ? 0xC2 : 0x31 ;
break ;
case XFER_MW_DMA_2 :
case XFER_MW_DMA_1 :
case XFER_MW_DMA_0 :
2010-01-18 10:18:26 +03:00
cmd64x_program_timings ( drive , speed ) ;
cmd64x: fix multiword and remove single-word DMA support
Fix the multiword DMA and drop the single-word DMA support (which nobody will
miss, I think). In order to do it, a number of changes was necessary:
- rename program_drive_counts() to program_cycle_times(), pass to it cycle's
total/active times instead of the clock counts, and convert them into the
active/recovery clocks there instead of cmd64x_tune_pio() -- this causes
quantize_timing() to also move;
- contrarywise, move all the code handling the address setup timing into
cmd64x_tune_pio(), so that setting MWDMA mode wouldn't change address setup;
- remove from the speedproc() method the bogus code pretending to set the DMA
timings by twiddling bits in the BMIDE status register, handle setting MWDMA
by just calling program_cycle_times(); while at it, improve the style of that
whole switch statement;
- stop fiddling with the DMA capable bits in the speedproc() method -- they do
not enable DMA, and are properly dealt with by the dma_host_{on,off} methods;
- don't set hwif->swdma_mask in the init_hwif() method anymore.
In addition to those changes, do the following:
- in cmd64x_tune_pio(), when writing to ARTTIM23 register preserve the interrupt
status bit, eliminate local_irq_{save|restore}() around this code as there's
*no* actual race with the interrupt handler, and move cmdprintk() to a more
fitting place -- after ide_get_best_pio_mode() call;
- make {arttim|drwtim}_regs arrays single-dimensional, indexed with drive->dn;
- rename {setup|recovery}_counts[] into more fitting {setup|recovery}_values[];
- in the speedproc() method, get rid of the duplicate reads/writes from/to the
UDIDETCRx registers and of the extra variable used to store the transfer mode
value after filtering, use another method of determining master/slave drive,
and cleanup useless parens;
- beautify cmdprintk() output here and there.
While at it, remove meaningless comment about the driver being used only on
UltraSPARC and long non-relevant RCS tag. :-)
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-05-06 00:03:49 +04:00
break ;
2005-04-17 02:20:36 +04:00
}
2010-01-18 10:18:38 +03:00
pci_write_config_byte ( dev , pciU , regU ) ;
2005-04-17 02:20:36 +04:00
}
2009-06-15 20:52:56 +04:00
static void cmd648_clear_irq ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2009-01-06 19:20:52 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2009-06-15 20:52:56 +04:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
unsigned long base = pci_resource_start ( dev , 4 ) ;
2007-05-06 00:03:50 +04:00
u8 irq_mask = hwif - > channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0 ;
2008-01-26 00:17:05 +03:00
u8 mrdmode = inb ( base + 1 ) ;
2007-05-06 00:03:50 +04:00
/* clear the interrupt bit */
2007-11-14 00:09:14 +03:00
outb ( ( mrdmode & ~ ( MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1 ) ) | irq_mask ,
2008-01-26 00:17:05 +03:00
base + 1 ) ;
2005-04-17 02:20:36 +04:00
}
2009-06-15 20:52:56 +04:00
static void cmd64x_clear_irq ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2009-01-06 19:20:52 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2008-02-02 01:09:31 +03:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
2007-05-06 00:03:50 +04:00
int irq_reg = hwif - > channel ? ARTTIM23 : CFR ;
u8 irq_mask = hwif - > channel ? ARTTIM23_INTR_CH1 :
CFR_INTR_CH0 ;
u8 irq_stat = 0 ;
2005-04-17 02:20:36 +04:00
2007-05-06 00:03:50 +04:00
( void ) pci_read_config_byte ( dev , irq_reg , & irq_stat ) ;
/* clear the interrupt bit */
( void ) pci_write_config_byte ( dev , irq_reg , irq_stat | irq_mask ) ;
}
2009-06-15 20:52:59 +04:00
static int cmd648_test_irq ( ide_hwif_t * hwif )
2007-05-06 00:03:50 +04:00
{
2009-06-15 20:52:59 +04:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
unsigned long base = pci_resource_start ( dev , 4 ) ;
2007-05-06 00:03:50 +04:00
u8 irq_mask = hwif - > channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0 ;
2008-01-26 00:17:05 +03:00
u8 mrdmode = inb ( base + 1 ) ;
2007-05-06 00:03:50 +04:00
2009-06-15 20:52:59 +04:00
pr_debug ( " %s: mrdmode: 0x%02x irq_mask: 0x%02x \n " ,
hwif - > name , mrdmode , irq_mask ) ;
2007-05-06 00:03:50 +04:00
2009-06-15 20:52:59 +04:00
return ( mrdmode & irq_mask ) ? 1 : 0 ;
2005-04-17 02:20:36 +04:00
}
2009-06-15 20:52:59 +04:00
static int cmd64x_test_irq ( ide_hwif_t * hwif )
2005-04-17 02:20:36 +04:00
{
2008-02-02 01:09:31 +03:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
2007-05-06 00:03:50 +04:00
int irq_reg = hwif - > channel ? ARTTIM23 : CFR ;
u8 irq_mask = hwif - > channel ? ARTTIM23_INTR_CH1 :
CFR_INTR_CH0 ;
u8 irq_stat = 0 ;
2007-05-06 00:03:49 +04:00
( void ) pci_read_config_byte ( dev , irq_reg , & irq_stat ) ;
2005-04-17 02:20:36 +04:00
2009-06-15 20:52:59 +04:00
pr_debug ( " %s: irq_stat: 0x%02x irq_mask: 0x%02x \n " ,
hwif - > name , irq_stat , irq_mask ) ;
2005-04-17 02:20:36 +04:00
2009-06-15 20:52:59 +04:00
return ( irq_stat & irq_mask ) ? 1 : 0 ;
2005-04-17 02:20:36 +04:00
}
/*
* ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
* event order for DMA transfers .
*/
2008-04-27 00:25:24 +04:00
static int cmd646_1_dma_end ( ide_drive_t * drive )
2005-04-17 02:20:36 +04:00
{
2009-01-06 19:20:52 +03:00
ide_hwif_t * hwif = drive - > hwif ;
2005-04-17 02:20:36 +04:00
u8 dma_stat = 0 , dma_cmd = 0 ;
/* get DMA status */
2008-07-23 21:55:51 +04:00
dma_stat = inb ( hwif - > dma_base + ATA_DMA_STATUS ) ;
2005-04-17 02:20:36 +04:00
/* read DMA command state */
2008-07-23 21:55:51 +04:00
dma_cmd = inb ( hwif - > dma_base + ATA_DMA_CMD ) ;
2005-04-17 02:20:36 +04:00
/* stop DMA */
2008-07-23 21:55:51 +04:00
outb ( dma_cmd & ~ 1 , hwif - > dma_base + ATA_DMA_CMD ) ;
2005-04-17 02:20:36 +04:00
/* clear the INTR & ERROR bits */
2008-07-23 21:55:51 +04:00
outb ( dma_stat | 6 , hwif - > dma_base + ATA_DMA_STATUS ) ;
2005-04-17 02:20:36 +04:00
/* verify good DMA status */
return ( dma_stat & 7 ) ! = 4 ;
}
2009-03-25 01:22:53 +03:00
static int init_chipset_cmd64x ( struct pci_dev * dev )
2005-04-17 02:20:36 +04:00
{
u8 mrdmode = 0 ;
/* Set a good latency timer and cache line size value. */
( void ) pci_write_config_byte ( dev , PCI_LATENCY_TIMER , 64 ) ;
/* FIXME: pci_set_master() to ensure a good latency timer value */
2007-07-10 01:17:55 +04:00
/*
* Enable interrupts , select MEMORY READ LINE for reads .
*
* NOTE : although not mentioned in the PCI0646U specs ,
* bits 0 - 1 are write only and won ' t be read back as
* set or not - - PCI0646U2 specs clarify this point .
2005-04-17 02:20:36 +04:00
*/
2007-07-10 01:17:55 +04:00
( void ) pci_read_config_byte ( dev , MRDMODE , & mrdmode ) ;
mrdmode & = ~ 0x30 ;
( void ) pci_write_config_byte ( dev , MRDMODE , ( mrdmode | 0x02 ) ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2008-08-05 20:17:04 +04:00
static u8 cmd64x_cable_detect ( ide_hwif_t * hwif )
2005-04-17 02:20:36 +04:00
{
2008-02-02 01:09:31 +03:00
struct pci_dev * dev = to_pci_dev ( hwif - > dev ) ;
2007-07-10 01:17:55 +04:00
u8 bmidecsr = 0 , mask = hwif - > channel ? 0x02 : 0x01 ;
2005-04-17 02:20:36 +04:00
2007-07-10 01:17:55 +04:00
switch ( dev - > device ) {
case PCI_DEVICE_ID_CMD_648 :
case PCI_DEVICE_ID_CMD_649 :
pci_read_config_byte ( dev , BMIDECSR , & bmidecsr ) ;
2007-07-10 01:17:58 +04:00
return ( bmidecsr & mask ) ? ATA_CBL_PATA80 : ATA_CBL_PATA40 ;
2007-07-10 01:17:55 +04:00
default :
2007-07-10 01:17:58 +04:00
return ATA_CBL_PATA40 ;
2005-04-17 02:20:36 +04:00
}
}
2008-04-27 00:25:14 +04:00
static const struct ide_port_ops cmd64x_port_ops = {
. set_pio_mode = cmd64x_set_pio_mode ,
. set_dma_mode = cmd64x_set_dma_mode ,
2009-06-15 20:52:56 +04:00
. clear_irq = cmd64x_clear_irq ,
2009-06-15 20:52:59 +04:00
. test_irq = cmd64x_test_irq ,
2009-06-15 20:52:56 +04:00
. cable_detect = cmd64x_cable_detect ,
} ;
static const struct ide_port_ops cmd648_port_ops = {
. set_pio_mode = cmd64x_set_pio_mode ,
. set_dma_mode = cmd64x_set_dma_mode ,
. clear_irq = cmd648_clear_irq ,
2009-06-15 20:52:59 +04:00
. test_irq = cmd648_test_irq ,
2008-04-27 00:25:14 +04:00
. cable_detect = cmd64x_cable_detect ,
} ;
2008-04-27 00:25:24 +04:00
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
. dma_host_set = ide_dma_host_set ,
. dma_setup = ide_dma_setup ,
. dma_start = ide_dma_start ,
2008-04-27 00:25:24 +04:00
. dma_end = cmd646_1_dma_end ,
2008-04-27 00:25:24 +04:00
. dma_test_irq = ide_dma_test_irq ,
. dma_lost_irq = ide_dma_lost_irq ,
2009-03-27 14:46:47 +03:00
. dma_timer_expiry = ide_dma_sff_timer_expiry ,
2009-01-06 19:21:02 +03:00
. dma_sff_read_status = ide_dma_sff_read_status ,
2008-04-27 00:25:24 +04:00
} ;
2012-12-22 01:21:03 +04:00
static const struct ide_port_info cmd64x_chipsets [ ] = {
2008-07-25 00:53:32 +04:00
{ /* 0: CMD643 */
. name = DRV_NAME ,
2005-04-17 02:20:36 +04:00
. init_chipset = init_chipset_cmd64x ,
2007-05-06 00:03:49 +04:00
. enablebits = { { 0x00 , 0x00 , 0x00 } , { 0x51 , 0x08 , 0x08 } } ,
2008-04-27 00:25:14 +04:00
. port_ops = & cmd64x_port_ops ,
2008-02-02 01:09:30 +03:00
. host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
2009-10-21 12:55:28 +04:00
IDE_HFLAG_ABUSE_PREFETCH |
IDE_HFLAG_SERIALIZE ,
2007-07-20 03:11:59 +04:00
. pio_mask = ATA_PIO5 ,
2007-10-19 02:30:07 +04:00
. mwdma_mask = ATA_MWDMA2 ,
2007-05-10 02:01:07 +04:00
. udma_mask = 0x00 , /* no udma */
2008-07-25 00:53:32 +04:00
} ,
{ /* 1: CMD646 */
. name = DRV_NAME ,
2005-04-17 02:20:36 +04:00
. init_chipset = init_chipset_cmd64x ,
2007-05-06 00:03:49 +04:00
. enablebits = { { 0x51 , 0x04 , 0x04 } , { 0x51 , 0x08 , 0x08 } } ,
2009-06-15 20:52:56 +04:00
. port_ops = & cmd648_port_ops ,
2009-10-21 12:55:28 +04:00
. host_flags = IDE_HFLAG_ABUSE_PREFETCH |
IDE_HFLAG_SERIALIZE ,
2007-07-20 03:11:59 +04:00
. pio_mask = ATA_PIO5 ,
2007-10-19 02:30:07 +04:00
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA2 ,
2008-07-25 00:53:32 +04:00
} ,
{ /* 2: CMD648 */
. name = DRV_NAME ,
2005-04-17 02:20:36 +04:00
. init_chipset = init_chipset_cmd64x ,
2007-05-06 00:03:49 +04:00
. enablebits = { { 0x51 , 0x04 , 0x04 } , { 0x51 , 0x08 , 0x08 } } ,
2009-06-15 20:52:56 +04:00
. port_ops = & cmd648_port_ops ,
2008-04-26 19:36:35 +04:00
. host_flags = IDE_HFLAG_ABUSE_PREFETCH ,
2007-07-20 03:11:59 +04:00
. pio_mask = ATA_PIO5 ,
2007-10-19 02:30:07 +04:00
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA4 ,
2008-07-25 00:53:32 +04:00
} ,
{ /* 3: CMD649 */
. name = DRV_NAME ,
2005-04-17 02:20:36 +04:00
. init_chipset = init_chipset_cmd64x ,
2007-05-06 00:03:49 +04:00
. enablebits = { { 0x51 , 0x04 , 0x04 } , { 0x51 , 0x08 , 0x08 } } ,
2009-06-15 20:52:56 +04:00
. port_ops = & cmd648_port_ops ,
2008-04-26 19:36:35 +04:00
. host_flags = IDE_HFLAG_ABUSE_PREFETCH ,
2007-07-20 03:11:59 +04:00
. pio_mask = ATA_PIO5 ,
2007-10-19 02:30:07 +04:00
. mwdma_mask = ATA_MWDMA2 ,
. udma_mask = ATA_UDMA5 ,
2005-04-17 02:20:36 +04:00
}
} ;
2012-12-22 01:21:03 +04:00
static int cmd64x_init_one ( struct pci_dev * dev , const struct pci_device_id * id )
2005-04-17 02:20:36 +04:00
{
2007-10-20 02:32:34 +04:00
struct ide_port_info d ;
2007-10-19 02:30:09 +04:00
u8 idx = id - > driver_data ;
d = cmd64x_chipsets [ idx ] ;
2008-04-27 00:25:24 +04:00
if ( idx = = 1 ) {
/*
* UltraDMA only supported on PCI646U and PCI646U2 , which
* correspond to revisions 0x03 , 0x05 and 0x07 respectively .
* Actually , although the CMD tech support people won ' t
* tell me the details , the 0x03 revision cannot support
* UDMA correctly without hardware modifications , and even
* then it only works with Quantum disks due to some
* hold time assumptions in the 646U part which are fixed
* in the 646U 2.
*
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets .
*/
if ( dev - > revision < 5 ) {
d . udma_mask = 0x00 ;
/*
* The original PCI0646 didn ' t have the primary
* channel enable bit , it appeared starting with
* PCI0646U ( i . e . revision ID 3 ) .
*/
if ( dev - > revision < 3 ) {
d . enablebits [ 0 ] . reg = 0 ;
2009-06-15 20:52:56 +04:00
d . port_ops = & cmd64x_port_ops ;
2008-04-27 00:25:24 +04:00
if ( dev - > revision = = 1 )
d . dma_ops = & cmd646_rev1_dma_ops ;
}
}
}
2007-05-06 00:03:49 +04:00
2008-07-25 00:53:14 +04:00
return ide_pci_init_one ( dev , & d , NULL ) ;
2005-04-17 02:20:36 +04:00
}
2007-10-17 00:29:56 +04:00
static const struct pci_device_id cmd64x_pci_tbl [ ] = {
{ PCI_VDEVICE ( CMD , PCI_DEVICE_ID_CMD_643 ) , 0 } ,
{ PCI_VDEVICE ( CMD , PCI_DEVICE_ID_CMD_646 ) , 1 } ,
{ PCI_VDEVICE ( CMD , PCI_DEVICE_ID_CMD_648 ) , 2 } ,
{ PCI_VDEVICE ( CMD , PCI_DEVICE_ID_CMD_649 ) , 3 } ,
2005-04-17 02:20:36 +04:00
{ 0 , } ,
} ;
MODULE_DEVICE_TABLE ( pci , cmd64x_pci_tbl ) ;
2008-10-13 23:39:41 +04:00
static struct pci_driver cmd64x_pci_driver = {
2005-04-17 02:20:36 +04:00
. name = " CMD64x_IDE " ,
. id_table = cmd64x_pci_tbl ,
. probe = cmd64x_init_one ,
2008-07-25 00:53:20 +04:00
. remove = ide_pci_remove ,
2008-10-11 00:39:32 +04:00
. suspend = ide_pci_suspend ,
. resume = ide_pci_resume ,
2005-04-17 02:20:36 +04:00
} ;
2007-01-27 15:46:56 +03:00
static int __init cmd64x_ide_init ( void )
2005-04-17 02:20:36 +04:00
{
2008-10-13 23:39:41 +04:00
return ide_pci_register_driver ( & cmd64x_pci_driver ) ;
2005-04-17 02:20:36 +04:00
}
2008-07-25 00:53:20 +04:00
static void __exit cmd64x_ide_exit ( void )
{
2008-10-13 23:39:41 +04:00
pci_unregister_driver ( & cmd64x_pci_driver ) ;
2008-07-25 00:53:20 +04:00
}
2005-04-17 02:20:36 +04:00
module_init ( cmd64x_ide_init ) ;
2008-07-25 00:53:20 +04:00
module_exit ( cmd64x_ide_exit ) ;
2005-04-17 02:20:36 +04:00
2010-01-18 10:18:26 +03:00
MODULE_AUTHOR ( " Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz " ) ;
2005-04-17 02:20:36 +04:00
MODULE_DESCRIPTION ( " PCI driver module for CMD64x IDE " ) ;
MODULE_LICENSE ( " GPL " ) ;