SATA core updates
PATCH 1/1 SATA core updates
Some updates to the SATA core (libata) are required to support SATA-II drivers. These updates (attached for 2.6.7-bk20) just change internals only; no behavior should change.
Testing is requested, to make sure I didn't break anything. Tested locally on sata_sil, ata_piix, sata_promise, sata_via and sata_sx4.
These changes are found in the libata-2.4 and libata-2.6 queues (BK info below), and also in patches for 2.4.x and 2.6.x:
http://www.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.4/2.4.27-rc3-libata1.patch.bz2
http://www.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.7-bk20-libata1.patch.bz2
bk://gkernel.bkbits.net/libata-2.4
bk://gkernel.bkbits.net/libata-2.6
BK users may do a
bk pull bk://gkernel.bkbits.net/libata-2.6
This will update the following files:
drivers/scsi/ata_piix.c | 81 +++-- drivers/scsi/libata-core.c | 611 ++++++++++++++++++++++++-------------------- drivers/scsi/libata-scsi.c | 9 drivers/scsi/sata_nv.c | 2 drivers/scsi/sata_promise.c | 77 ++--- drivers/scsi/sata_sil.c | 7 drivers/scsi/sata_sis.c | 3 drivers/scsi/sata_svw.c | 1 drivers/scsi/sata_sx4.c | 165 +++++++---- drivers/scsi/sata_via.c | 1 drivers/scsi/sata_vsc.c | 1 include/linux/ata.h | 7 include/linux/libata.h | 25 + 13 files changed, 571 insertions(+), 419 deletions(-)
through these ChangeSets:
<[email protected]> (04/07/07 1.1844)
[libata] update IDENTIFY DEVICE path to use ata_queued_cmd
rather than hand-rolling our own taskfile call (which won't work at all on newer SATA controllers).
Individual changes:
* use ata_qc_issue to issue identify-device command
* implement MMIO path for PIO data xfer
* implement PIO error handling path
<[email protected]> (04/07/07 1.1841.1.1)
[libata] pio/dma flag bug fix, and cleanup
In the transfer-mode cleanup recently, the code that set flag ATA_DFLAG_PIO disappeared. Resurrect it.
Remove ATA_QCFLAG_DMA, it isn't needed.
Always set polling in the ->qc_issue function, rather than force the user to do it when setting up an ata_queued_cmd. This gives maximum flexibility to the driver, letting the driver choose whether or not to poll.
<[email protected]> (04/07/05 1.1757.57.14)
[libata sata_sx4] deliver non-data taskfiles using Promise packet format
<[email protected]> (04/07/04 1.1757.57.13)
[libata sata_promise] convert to using packets for non-data taskfiles
<[email protected]> (04/07/04 1.1757.58.1)
[libata] transfer mode bug fixes and type cleanup
Fix two bugs that causes the recently-added transfer mode code to break on 64-bit platforms. Make associated code more type-correct in the process.
<[email protected]> (04/07/04 1.1757.57.11)
[libata] convert set-xfer-mode operation to use ata_queued_cmd
<[email protected]> (04/07/04 1.1757.57.10)
[libata] fix completion bug, better debug output
When using a completion, we need to clear the entry, and furthermore clear the entry before we call the completion.
Make debugging output a bit more explicit.
<[email protected]> (04/07/04 1.1757.57.9)
[libata] transfer mode cleanup
Add MWDMA support, and rework pio/mwdma/udma mode setup.
In the lone test case for PATA support, ata_piix, MWDMA mode setting does not appear to work here. UDMA and PIO continue to work, so nobody will really notice. But beware. Probably a driver problem, not a bug in the core.
Also, doesn't bother writing to dummy timing registers on ICH5/6 SATA anymore.
drivers/scsi/ata_piix.c +51 -30
@@ -65,10 +65,8 @@static void piix_pata_phy_reset (struct ata_port *ap);static void piix_sata_phy_reset (struct ata_port *ap); -static void piix_set_piomode (struct ata_port *ap,struct ata_device *adev, -unsigned int pio); -static void piix_set_udmamode (struct ata_port *ap,struct ata_device *adev, -unsigned int udma); +static void piix_set_piomode (struct ata_port *ap,struct ata_device *adev); +static void piix_set_dmamode (struct ata_port *ap,struct ata_device *adev);static unsigned int in_module_init =1 ;
@@ -126,7 +124,7 @@static struct ata_port_operations piix_pata_ops = { .port_disable = ata_port_disable, .set_piomode = piix_set_piomode, - .set_udmamode = piix_set_udmamode, + .set_dmamode = piix_set_dmamode, .tf_load = ata_tf_load_pio, .tf_read = ata_tf_read_pio,
@@ -151,8 +149,6 @@static struct ata_port_operations piix_sata_ops = { .port_disable = ata_port_disable, - .set_piomode = piix_set_piomode, - .set_udmamode = piix_set_udmamode, .tf_load = ata_tf_load_pio, .tf_read = ata_tf_read_pio,
@@ -181,7 +177,12 @@ .sht = &piix_sht, .host_flags =ATA_FLAG_SLAVE_POSS |ATA_FLAG_SRST | PIIX_FLAG_CHECKINTR, - .pio_mask = 0x03, /* pio3-4 */ + .pio_mask =0x1f ,/* pio0-4 */ +#if 0 + .mwdma_mask =0x06 ,/* mwdma1-2 */ +#else + .mwdma_mask = 0x00, /* mwdma broken */ +#endif .udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */ .port_ops = &piix_pata_ops, },
@@ -191,8 +192,9 @@ .sht = &piix_sht, .host_flags =ATA_FLAG_SATA |ATA_FLAG_SRST | PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR, - .pio_mask = 0x03, /* pio3-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &piix_sata_ops, },
@@ -200,7 +202,12 @@ { .sht = &piix_sht, .host_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, - .pio_mask = 0x03, /* pio3-4 */ + .pio_mask =0x1f ,/* pio0-4 */ +#if 0 + .mwdma_mask =0x06 ,/* mwdma1-2 */ +#else + .mwdma_mask = 0x00, /* mwdma broken */ +#endif .udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */ .port_ops = &piix_pata_ops, },
@@ -211,8 +218,9 @@ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST | PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR | ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x03, /* pio3-4 */ - .udma_mask = 0x7f, /* udma0-6 ; FIXME */ + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = 0x7f, /* udma0-6 */ .port_ops = &piix_sata_ops, }, };
@@ -368,9 +376,9 @@* None (inherited from caller). */ -static void piix_set_piomode (struct ata_port *ap,struct ata_device *adev, -unsigned int pio) +static void piix_set_piomode (struct ata_port *ap,struct ata_device *adev) { +unsigned int pio = adev->pio_mode;struct pci_dev *dev = ap->host_set->pdev;unsigned int is_slave = (adev->flags &ATA_DFLAG_MASTER ) ?0 :1 ;unsigned int master_port= ap->port_no ?0x42 :0x40 ;
@@ -409,7 +417,7 @@ }/** -* piix_set_udmamode - Initialize host controller PATA PIO timings +* piix_set_dmamode - Initialize host controller PATA PIO timings * @ap: Port whose timings we are configuring * @adev: um * @udma: udma mode, 0 - 6
@@ -420,9 +428,9 @@* None (inherited from caller). */ -static void piix_set_udmamode (struct ata_port *ap,struct ata_device *adev, -unsigned int udma) +static void piix_set_dmamode (struct ata_port *ap,struct ata_device *adev) { +unsigned int udma = adev->dma_mode;/* FIXME: MWDMA too */ struct pci_dev *dev = ap->host_set->pdev;u8 maslave = ap->port_no ?0x42 :0x40 ;u8 speed = udma;
@@ -452,25 +460,38 @@case XFER_UDMA_3 :case XFER_UDMA_1 : u_speed =1 << (drive_dn *4 );break ;case XFER_UDMA_0 : u_speed =0 << (drive_dn *4 );break ; +case XFER_MW_DMA_2 : +case XFER_MW_DMA_1 :break ;default :BUG ();return ; } -if (!(reg48 & u_flag)) -pci_write_config_byte (dev,0x48 , reg48 | u_flag); -if (speed ==XFER_UDMA_5 ) { -pci_write_config_byte (dev,0x55 , (u8 ) reg55|w_flag); +if (speed >=XFER_UDMA_0 ) { +if (!(reg48 & u_flag)) +pci_write_config_byte (dev,0x48 , reg48 | u_flag); +if (speed ==XFER_UDMA_5 ) { +pci_write_config_byte (dev,0x55 , (u8 ) reg55|w_flag); + }else { +pci_write_config_byte (dev,0x55 , (u8 ) reg55 & ~w_flag); + } +if ((reg4a & a_speed) != u_speed) +pci_write_config_word (dev,0x4a , (reg4a & ~a_speed) | u_speed); +if (speed >XFER_UDMA_2 ) { +if (!(reg54 & v_flag)) +pci_write_config_byte (dev,0x54 , reg54 | v_flag); + }else +pci_write_config_byte (dev,0x54 , reg54 & ~v_flag); }else { -pci_write_config_byte (dev,0x55 , (u8 ) reg55 & ~w_flag); +if (reg48 & u_flag) +pci_write_config_byte (dev,0x48 , reg48 & ~u_flag); +if (reg4a & a_speed) +pci_write_config_word (dev,0x4a , reg4a & ~a_speed); +if (reg54 & v_flag) +pci_write_config_byte (dev,0x54 , reg54 & ~v_flag); +if (reg55 & w_flag) +pci_write_config_byte (dev,0x55 , (u8 ) reg55 & ~w_flag); } -if ((reg4a & a_speed) != u_speed) -pci_write_config_word (dev,0x4a , (reg4a & ~a_speed) | u_speed); -if (speed >XFER_UDMA_2 ) { -if (!(reg54 & v_flag)) -pci_write_config_byte (dev,0x54 , reg54 | v_flag); - }else -pci_write_config_byte (dev,0x54 , reg54 & ~v_flag); }/* move to PCI layer, integrate w/ MSI stuff */
drivers/scsi/libata-core.c +347 -264
871 lines not on this page · raw message
drivers/scsi/libata-scsi.c +5 -4
@@ -979,6 +979,8 @@static unsigned int atapi_xlat (struct ata_queued_cmd *qc,u8 *scsicmd) {struct scsi_cmnd *cmd = qc->scsicmd; +struct ata_device *dev = qc->dev; +int using_pio = (dev->flags &ATA_DFLAG_PIO ); qc->tf.flags |=ATA_TFLAG_ISADDR |ATA_TFLAG_DEVICE ;if (cmd->sc_data_direction ==SCSI_DATA_WRITE ) {
@@ -992,14 +994,13 @@if (cmd->sc_data_direction ==SCSI_DATA_NONE ) qc->tf.protocol =ATA_PROT_ATAPI ; -/* PIO data xfer - polling */ -else if ((qc->flags &ATA_QCFLAG_DMA ) ==0 ) { -ata_qc_set_polling (qc); +/* PIO data xfer */ +else if (using_pio) { qc->tf.protocol =ATA_PROT_ATAPI ; qc->tf.lbam = (8 *1024 ) &0xff ; qc->tf.lbah = (8 *1024 ) >>8 ; -/* DMA data xfer - interrupt-driven */ +/* DMA data xfer */ }else { qc->tf.protocol =ATA_PROT_ATAPI_DMA ; qc->tf.feature |=ATAPI_PKT_DMA ;
drivers/scsi/sata_nv.c +2 -0
@@ -39,6 +39,7 @@#define NV_PORTS 2#define NV_PIO_MASK 0x1f +#define NV_MWDMA_MASK 0x07#define NV_UDMA_MASK 0x7f#define NV_PORT0_BMDMA_REG_OFFSET 0x00#define NV_PORT1_BMDMA_REG_OFFSET 0x08
@@ -289,6 +290,7 @@ probe_ent->irq = pdev->irq; probe_ent->irq_flags =SA_SHIRQ ; probe_ent->pio_mask =NV_PIO_MASK ; + probe_ent->mwdma_mask =NV_MWDMA_MASK ; probe_ent->udma_mask =NV_UDMA_MASK ; probe_ent->port[0 ].cmd_addr =pci_resource_start (pdev,0 );
drivers/scsi/sata_promise.c +33 -44
160 lines not on this page · raw message
drivers/scsi/sata_sil.c +5 -2
@@ -149,7 +149,8 @@ .sht = &sil_sht, .host_flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO, - .pio_mask = 0x03, /* pio3-4 */ + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, }, /* sil_3114 */
@@ -157,7 +158,8 @@ .sht = &sil_sht, .host_flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | ATA_FLAG_MMIO, - .pio_mask = 0x03, /* pio3-4 */ + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, },
@@ -363,6 +365,7 @@ probe_ent->sht = sil_port_info[ent->driver_data].sht; probe_ent->n_ports = (ent->driver_data == sil_3114) ?4 :2 ; probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask; + probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask; probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask; probe_ent->irq = pdev->irq; probe_ent->irq_flags =SA_SHIRQ ;
drivers/scsi/sata_sis.c +2 -1
@@ -230,7 +230,8 @@ probe_ent->host_flags |=SIS_FLAG_CFGSCR ; } - probe_ent->pio_mask =0x03 ; + probe_ent->pio_mask =0x1f ; + probe_ent->mwdma_mask =0x7 ; probe_ent->udma_mask =0x7f ; probe_ent->port_ops = &sis_ops;
drivers/scsi/sata_svw.c +1 -0
@@ -343,6 +343,7 @@* if we don't fill these */ probe_ent->pio_mask =0x1f ; + probe_ent->mwdma_mask =0x7 ; probe_ent->udma_mask =0x7f ;/* We have 4 ports per PCI function */
drivers/scsi/sata_sx4.c +100 -65
299 lines not on this page · raw message
drivers/scsi/sata_via.c +1 -0
@@ -214,6 +214,7 @@ probe_ent->irq = pdev->irq; probe_ent->irq_flags =SA_SHIRQ ; probe_ent->pio_mask =0x1f ; + probe_ent->mwdma_mask =0x07 ; probe_ent->udma_mask =0x7f ; probe_ent->port[0 ].cmd_addr =pci_resource_start (pdev,0 );
drivers/scsi/sata_vsc.c +1 -0
@@ -320,6 +320,7 @@* if we don't fill these */ probe_ent->pio_mask =0x1f ; + probe_ent->mwdma_mask =0x07 ; probe_ent->udma_mask =0x7f ;/* We have 4 ports per PCI function */
include/linux/ata.h +7 -0
@@ -42,6 +42,7 @@ATA_ID_SERNO_OFS =10 ,ATA_ID_MAJOR_VER =80 ,ATA_ID_PIO_MODES =64 , +ATA_ID_MWDMA_MODES =63 ,ATA_ID_UDMA_MODES =88 , ATA_ID_PIO4 = (1 << 1),
@@ -133,8 +134,14 @@XFER_UDMA_2 =0x42 ,XFER_UDMA_1 =0x41 ,XFER_UDMA_0 =0x40 , +XFER_MW_DMA_2 =0x22 , +XFER_MW_DMA_1 =0x21 , +XFER_MW_DMA_0 =0x20 ,XFER_PIO_4 =0x0C ,XFER_PIO_3 =0x0B , +XFER_PIO_2 =0x0A , +XFER_PIO_1 =0x09 , +XFER_PIO_0 =0x08 ,/* ATAPI stuff */ ATAPI_PKT_DMA = (1 << 0),
include/linux/libata.h +16 -9
@@ -32,7 +32,6 @@/* * compile-time options */ -#undef ATA_FORCE_PIO/* do not configure or use DMA */ #undef ATA_DEBUG/* debugging output */ #undef ATA_VERBOSE_DEBUG/* yet more debugging output */ #undef ATA_IRQ_TRAP/* define to ack screaming irqs */
@@ -111,7 +110,6 @@ATA_FLAG_SATA_RESET = (1 <<7 ),/* use COMRESET */ ATA_QCFLAG_ACTIVE = (1 <<1 ),/* cmd not yet ack'd to scsi lyer */ -ATA_QCFLAG_DMA = (1 <<2 ),/* data delivered via DMA */ ATA_QCFLAG_SG = (1 <<3 ),/* have s/g table? */ ATA_QCFLAG_SINGLE = (1 <<4 ),/* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
@@ -140,6 +138,13 @@PORT_UNKNOWN =0 ,PORT_ENABLED =1 ,PORT_DISABLED =2 , + +/* encoding various smaller bitmaps into a single +* unsigned long bitmap +*/ +ATA_SHIFT_UDMA =0 , +ATA_SHIFT_MWDMA =8 , + ATA_SHIFT_PIO = 11, }; enum pio_task_states {
@@ -188,6 +193,7 @@struct ata_ioports port[ATA_MAX_PORTS ];unsigned int n_ports;unsigned int pio_mask; +unsigned int mwdma_mask;unsigned int udma_mask;unsigned int legacy_mode;unsigned long irq;
@@ -251,8 +257,10 @@unsigned int class;/* ATA_DEV_xxx */ unsigned int devno;/* 0 or 1 */ u16 id[ATA_ID_WORDS ];/* IDENTIFY xxx DEVICE data */ -unsigned int pio_mode; -unsigned int udma_mode; +u8 pio_mode; +u8 dma_mode; +u8 xfer_mode; +unsigned int xfer_shift;/* ATA_SHIFT_xxx */ /* cache info about current transfer mode */ u8 xfer_protocol;/* taskfile xfer protocol */
@@ -277,6 +285,7 @@unsigned int bus_state;unsigned int port_state;unsigned int pio_mask; +unsigned int mwdma_mask;unsigned int udma_mask;unsigned int cbl;/* cable type; ATA_CBL_xxx */
@@ -303,10 +312,8 @@void (*dev_config) (struct ata_port *,struct ata_device *); -void (*set_piomode) (struct ata_port *,struct ata_device *, -unsigned int ); -void (*set_udmamode) (struct ata_port *,struct ata_device *, -unsigned int ); +void (*set_piomode) (struct ata_port *,struct ata_device *); +void (*set_dmamode) (struct ata_port *,struct ata_device *);void (*tf_load) (struct ata_port *ap,struct ata_taskfile *tf);void (*tf_read) (struct ata_port *ap,struct ata_taskfile *tf);
@@ -342,6 +349,7 @@Scsi_Host_Template *sht;unsigned long host_flags;unsigned long pio_mask; +unsigned long mwdma_mask;unsigned long udma_mask;struct ata_port_operations *port_ops; };
@@ -472,7 +480,6 @@static inline void ata_qc_set_polling (struct ata_queued_cmd *qc) { - qc->flags &= ~ATA_QCFLAG_DMA ; qc->tf.ctl |=ATA_NIEN ; }