Commit 049a1ca4 authored by Jeff Garzik's avatar Jeff Garzik

[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.
parent 2b50a905
......@@ -65,10 +65,8 @@ static int piix_init_one (struct pci_dev *pdev,
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 Scsi_Host_Template piix_sht = {
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_pata_ops = {
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 @@ static struct ata_port_info piix_port_info[] = {
.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 @@ static struct ata_port_info piix_port_info[] = {
.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 @@ static struct ata_port_info piix_port_info[] = {
{
.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 @@ static struct ata_port_info piix_port_info[] = {
.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 @@ static void piix_sata_phy_reset(struct ata_port *ap)
* 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 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
}
/**
* 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 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev,
* 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 @@ static void piix_set_udmamode (struct ata_port *ap, struct ata_device *adev,
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 */
......
......@@ -50,11 +50,13 @@ static unsigned int ata_busy_sleep (struct ata_port *ap,
unsigned long tmout_pat,
unsigned long tmout);
static void __ata_dev_select (struct ata_port *ap, unsigned int device);
static void ata_host_set_pio(struct ata_port *ap);
static void ata_host_set_udma(struct ata_port *ap);
static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
static void ata_dev_set_udma(struct ata_port *ap, unsigned int device);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
static int fgb(unsigned long bitmap);
static int ata_choose_xfer_mode(struct ata_port *ap,
unsigned int *xfer_mode_out,
unsigned int *xfer_shift_out);
static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq;
......@@ -524,7 +526,7 @@ static void ata_dev_set_protocol(struct ata_device *dev)
dev->write_cmd = (cmd >> 8) & 0xff;
}
static const char * udma_str[] = {
static const char * xfer_mode_str[] = {
"UDMA/16",
"UDMA/25",
"UDMA/33",
......@@ -533,6 +535,14 @@ static const char * udma_str[] = {
"UDMA/100",
"UDMA/133",
"UDMA7",
"MWDMA0",
"MWDMA1",
"MWDMA2",
"PIO0",
"PIO1",
"PIO2",
"PIO3",
"PIO4",
};
/**
......@@ -550,16 +560,24 @@ static const char * udma_str[] = {
* @udma_mask, or the constant C string "<n/a>".
*/
static const char *ata_udma_string(unsigned int udma_mask)
static const char *ata_mode_string(unsigned int mask)
{
int i;
for (i = 7; i >= 0; i--) {
if (udma_mask & (1 << i))
return udma_str[i];
}
for (i = 7; i >= 0; i--)
if (mask & (1 << i))
goto out;
for (i = ATA_SHIFT_MWDMA + 2; i >= ATA_SHIFT_MWDMA; i--)
if (mask & (1 << i))
goto out;
for (i = ATA_SHIFT_PIO + 4; i >= ATA_SHIFT_PIO; i--)
if (mask & (1 << i))
goto out;
return "<n/a>";
out:
return xfer_mode_str[i];
}
/**
......@@ -930,7 +948,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
unsigned int i;
u16 tmp, udma_modes;
u16 tmp, xfer_modes;
u8 status;
struct ata_taskfile tf;
unsigned int using_edd;
......@@ -1046,11 +1064,12 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
}
/* we require UDMA support */
udma_modes =
tmp = dev->id[ATA_ID_UDMA_MODES];
if ((tmp & 0xff) == 0) {
printk(KERN_DEBUG "ata%u: no udma\n", ap->id);
goto err_out_nosup;
xfer_modes = dev->id[ATA_ID_UDMA_MODES];
if (!xfer_modes)
xfer_modes = (dev->id[ATA_ID_MWDMA_MODES]) << ATA_SHIFT_MWDMA;
if (!xfer_modes) {
xfer_modes = (dev->id[ATA_ID_PIO_MODES]) << (ATA_SHIFT_PIO + 3);
xfer_modes |= (0x7 << ATA_SHIFT_PIO);
}
ata_dump_id(dev);
......@@ -1083,7 +1102,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n",
ap->id, device,
ata_udma_string(udma_modes),
ata_mode_string(xfer_modes),
(unsigned long long)dev->n_sectors,
dev->flags & ATA_DFLAG_LBA48 ? " lba48" : "");
}
......@@ -1101,7 +1120,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
/* print device info to dmesg */
printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n",
ap->id, device,
ata_udma_string(udma_modes));
ata_mode_string(xfer_modes));
}
DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap));
......@@ -1232,6 +1251,89 @@ void ata_port_disable(struct ata_port *ap)
ap->flags |= ATA_FLAG_PORT_DISABLED;
}
static struct {
unsigned int shift;
unsigned int base;
} xfer_mode_classes[] = {
{ ATA_SHIFT_UDMA, XFER_UDMA_0 },
{ ATA_SHIFT_MWDMA, XFER_MW_DMA_0 },
{ ATA_SHIFT_PIO, XFER_PIO_0 },
};
static inline unsigned int base_from_shift(unsigned int shift)
{
int i;
for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++)
if (xfer_mode_classes[i].shift == shift)
return xfer_mode_classes[i].base;
return 0xffffffff;
}
static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev)
{
unsigned int base, offset;
if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
return;
ata_dev_set_xfermode(ap, dev);
base = base_from_shift(dev->xfer_shift);
offset = dev->xfer_mode - base;
printk(KERN_INFO "ata%u: dev %u configured for %s\n",
ap->id, dev->devno,
xfer_mode_str[offset + dev->xfer_shift]);
}
static int ata_host_set_pio(struct ata_port *ap)
{
unsigned int mask, base, xfer_mode;
int x, i;
mask = ata_get_mode_mask(ap, ATA_SHIFT_PIO);
x = fgb(mask);
if (x < 0) {
printk(KERN_WARNING "ata%u: no PIO support\n", ap->id);
return -1;
}
base = base_from_shift(ATA_SHIFT_PIO);
xfer_mode = base + x;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
if (ata_dev_present(dev)) {
dev->pio_mode = xfer_mode;
dev->xfer_mode = xfer_mode;
dev->xfer_shift = ATA_SHIFT_PIO;
if (ap->ops->set_piomode)
ap->ops->set_piomode(ap, dev);
}
}
return 0;
}
static void ata_host_set_dma(struct ata_port *ap, unsigned int xfer_mode,
unsigned int xfer_shift)
{
int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
if (ata_dev_present(dev)) {
dev->dma_mode = xfer_mode;
dev->xfer_mode = xfer_mode;
dev->xfer_shift = xfer_shift;
if (ap->ops->set_dmamode)
ap->ops->set_dmamode(ap, dev);
}
}
}
/**
* ata_set_mode - Program timings and issue SET FEATURES - XFER
* @ap: port on which timings will be programmed
......@@ -1241,29 +1343,27 @@ void ata_port_disable(struct ata_port *ap)
*/
static void ata_set_mode(struct ata_port *ap)
{
unsigned int force_pio, i;
unsigned int i, xfer_mode, xfer_shift;
int rc;
ata_host_set_pio(ap);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
/* step 1: always set host PIO timings */
rc = ata_host_set_pio(ap);
if (rc)
goto err_out;
ata_host_set_udma(ap);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
/* step 2: choose the best data xfer mode */
xfer_mode = xfer_shift = 0;
rc = ata_choose_xfer_mode(ap, &xfer_mode, &xfer_shift);
if (rc)
goto err_out;
#ifdef ATA_FORCE_PIO
force_pio = 1;
#else
force_pio = 0;
#endif
/* step 3: if that xfer mode isn't PIO, set host DMA timings */
if (xfer_shift != ATA_SHIFT_PIO)
ata_host_set_dma(ap, xfer_mode, xfer_shift);
if (force_pio) {
ata_dev_set_pio(ap, 0);
ata_dev_set_pio(ap, 1);
} else {
ata_dev_set_udma(ap, 0);
ata_dev_set_udma(ap, 1);
}
/* step 4: update devices' xfer mode */
ata_dev_set_mode(ap, &ap->device[0]);
ata_dev_set_mode(ap, &ap->device[1]);
if (ap->flags & ATA_FLAG_PORT_DISABLED)
return;
......@@ -1275,6 +1375,11 @@ static void ata_set_mode(struct ata_port *ap)
struct ata_device *dev = &ap->device[i];
ata_dev_set_protocol(dev);
}
return;
err_out:
ata_port_disable(ap);
}
/**
......@@ -1536,116 +1641,101 @@ void ata_bus_reset(struct ata_port *ap)
DPRINTK("EXIT\n");
}
/**
* ata_host_set_pio -
* @ap:
*
* LOCKING:
*/
static void ata_host_set_pio(struct ata_port *ap)
static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift)
{
struct ata_device *master, *slave;
unsigned int pio, i;
u16 mask;
unsigned int mask;
master = &ap->device[0];
slave = &ap->device[1];
assert (ata_dev_present(master) || ata_dev_present(slave));
mask = ap->pio_mask;
if (ata_dev_present(master))
mask &= (master->id[ATA_ID_PIO_MODES] & 0x03);
if (ata_dev_present(slave))
mask &= (slave->id[ATA_ID_PIO_MODES] & 0x03);
/* require pio mode 3 or 4 support for host and all devices */
if (mask == 0) {
printk(KERN_WARNING "ata%u: no PIO3/4 support, ignoring\n",
ap->id);
goto err_out;
if (shift == ATA_SHIFT_UDMA) {
mask = ap->udma_mask;
if (ata_dev_present(master))
mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
if (ata_dev_present(slave))
mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
}
else if (shift == ATA_SHIFT_MWDMA) {
mask = ap->mwdma_mask;
if (ata_dev_present(master))
mask &= (master->id[ATA_ID_MWDMA_MODES] & 0x07);
if (ata_dev_present(slave))
mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07);
}
else if (shift == ATA_SHIFT_PIO) {
mask = ap->pio_mask;
if (ata_dev_present(master)) {
/* spec doesn't return explicit support for
* PIO0-2, so we fake it
*/
u16 tmp_mode = master->id[ATA_ID_PIO_MODES] & 0x03;
tmp_mode <<= 3;
tmp_mode |= 0x7;
mask &= tmp_mode;
}
if (ata_dev_present(slave)) {
/* spec doesn't return explicit support for
* PIO0-2, so we fake it
*/
u16 tmp_mode = slave->id[ATA_ID_PIO_MODES] & 0x03;
tmp_mode <<= 3;
tmp_mode |= 0x7;
mask &= tmp_mode;
}
}
else {
mask = 0xffffffff; /* shut up compiler warning */
BUG();
}
pio = (mask & ATA_ID_PIO4) ? 4 : 3;
for (i = 0; i < ATA_MAX_DEVICES; i++)
if (ata_dev_present(&ap->device[i])) {
ap->device[i].pio_mode = (pio == 3) ?
XFER_PIO_3 : XFER_PIO_4;
if (ap->ops->set_piomode)
ap->ops->set_piomode(ap, &ap->device[i], pio);
}
return mask;
}
return;
/* find greatest bit */
static int fgb(unsigned long bitmap)
{
int i, x = -1;
err_out:
ap->ops->port_disable(ap);
for (i = 0; i < (sizeof(unsigned long) * 8); i++)
if (bitmap & (1 << i))
x = i;
return x;
}
/**
* ata_host_set_udma -
* ata_choose_xfer_mode -
* @ap:
*
* LOCKING:
*
* RETURNS:
* Zero on success, negative on error.
*/
static void ata_host_set_udma(struct ata_port *ap)
static int ata_choose_xfer_mode(struct ata_port *ap,
unsigned int *xfer_mode_out,
unsigned int *xfer_shift_out)
{
struct ata_device *master, *slave;
u16 mask;
unsigned int i, j;
int udma_mode = -1;
unsigned int mask, shift;
int x, i;
master = &ap->device[0];
slave = &ap->device[1];
for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) {
shift = xfer_mode_classes[i].shift;
mask = ata_get_mode_mask(ap, shift);
assert (ata_dev_present(master) || ata_dev_present(slave));
assert ((ap->flags & ATA_FLAG_PORT_DISABLED) == 0);
DPRINTK("udma masks: host 0x%X, master 0x%X, slave 0x%X\n",
ap->udma_mask,
(!ata_dev_present(master)) ? 0xff :
(master->id[ATA_ID_UDMA_MODES] & 0xff),
(!ata_dev_present(slave)) ? 0xff :
(slave->id[ATA_ID_UDMA_MODES] & 0xff));
mask = ap->udma_mask;
if (ata_dev_present(master))
mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff);
if (ata_dev_present(slave))
mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff);
i = XFER_UDMA_7;
while (i >= XFER_UDMA_0) {
j = i - XFER_UDMA_0;
DPRINTK("mask 0x%X i 0x%X j %u\n", mask, i, j);
if (mask & (1 << j)) {
udma_mode = i;
break;
x = fgb(mask);
if (x >= 0) {
*xfer_mode_out = xfer_mode_classes[i].base + x;
*xfer_shift_out = shift;
return 0;
}
i--;
}
/* require udma for host and all attached devices */
if (udma_mode < 0) {
printk(KERN_WARNING "ata%u: no UltraDMA support, ignoring\n",
ap->id);
goto err_out;
}
for (i = 0; i < ATA_MAX_DEVICES; i++)
if (ata_dev_present(&ap->device[i])) {
ap->device[i].udma_mode = udma_mode;
if (ap->ops->set_udmamode)
ap->ops->set_udmamode(ap, &ap->device[i],
udma_mode);
}
return;
err_out:
ap->ops->port_disable(ap);
return -1;
}
/**
......@@ -1668,10 +1758,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
tf.feature = SETFEATURES_XFER;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.protocol = ATA_PROT_NODATA;
if (dev->flags & ATA_DFLAG_PIO)
tf.nsect = dev->pio_mode;
else
tf.nsect = dev->udma_mode;
tf.nsect = dev->xfer_mode;
/* do bus reset */
ata_tf_to_host(ap, &tf);
......@@ -1689,57 +1776,6 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
DPRINTK("EXIT\n");
}
/**
* ata_dev_set_udma - Set ATA device's transfer mode to Ultra DMA
* @ap: Port associated with device @dev
* @device: Device whose mode will be set
*
* LOCKING:
*/
static void ata_dev_set_udma(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
return;
ata_dev_set_xfermode(ap, dev);
assert((dev->udma_mode >= XFER_UDMA_0) &&
(dev->udma_mode <= XFER_UDMA_7));
printk(KERN_INFO "ata%u: dev %u configured for %s\n",
ap->id, device,
udma_str[dev->udma_mode - XFER_UDMA_0]);
}
/**
* ata_dev_set_pio - Set ATA device's transfer mode to PIO
* @ap: Port associated with device @dev
* @device: Device whose mode will be set
*
* LOCKING:
*/
static void ata_dev_set_pio(struct ata_port *ap, unsigned int device)
{
struct ata_device *dev = &ap->device[device];
if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED))
return;
/* force PIO mode */
dev->flags |= ATA_DFLAG_PIO;
ata_dev_set_xfermode(ap, dev);
assert((dev->pio_mode >= XFER_PIO_3) &&
(dev->pio_mode <= XFER_PIO_4));
printk(KERN_INFO "ata%u: dev %u configured for PIO%c\n",
ap->id, device,
dev->pio_mode == 3 ? '3' : '4');
}
/**
* ata_sg_clean -
* @qc:
......@@ -2801,6 +2837,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->host_set = host_set;
ap->port_no = port_no;
ap->pio_mask = ent->pio_mask;
ap->mwdma_mask = ent->mwdma_mask;
ap->udma_mask = ent->udma_mask;
ap->flags |= ent->host_flags;
ap->ops = ent->port_ops;
......@@ -2898,19 +2935,23 @@ int ata_device_add(struct ata_probe_ent *ent)
/* register each port bound to this device */
for (i = 0; i < ent->n_ports; i++) {
struct ata_port *ap;
unsigned int xfer_mode_mask;
ap = ata_host_add(ent, host_set, i);
if (!ap)
goto err_out;
host_set->ports[i] = ap;
xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
(ap->pio_mask << ATA_SHIFT_PIO);
/* print per-port info to dmesg */
printk(KERN_INFO "ata%u: %cATA max %s cmd 0x%lX ctl 0x%lX "
"bmdma 0x%lX irq %lu\n",
ap->id,
ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
ata_udma_string(ent->udma_mask),
ata_mode_string(xfer_mode_mask),
ap->ioaddr.cmd_addr,
ap->ioaddr.ctl_addr,
ap->ioaddr.bmdma_addr,
......@@ -3149,6 +3190,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
probe_ent->sht = port0->sht;
probe_ent->host_flags = port0->host_flags;
probe_ent->pio_mask = port0->pio_mask;
probe_ent->mwdma_mask = port0->mwdma_mask;
probe_ent->udma_mask = port0->udma_mask;
probe_ent->port_ops = port0->port_ops;
......@@ -3171,6 +3213,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
probe_ent2->sht = port1->sht;
probe_ent2->host_flags = port1->host_flags;
probe_ent2->pio_mask = port1->pio_mask;
probe_ent2->mwdma_mask = port1->mwdma_mask;
probe_ent2->udma_mask = port1->udma_mask;
probe_ent2->port_ops = port1->port_ops;
} else {
......
......@@ -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 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
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);
......
......@@ -130,7 +130,8 @@ static struct ata_port_info pdc_port_info[] = {
.sht = &pdc_sata_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 = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &pdc_sata_ops,
},
......@@ -140,7 +141,8 @@ static struct ata_port_info pdc_port_info[] = {
.sht = &pdc_sata_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 = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &pdc_sata_ops,
},
......@@ -601,6 +603,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent->sht = pdc_port_info[board_idx].sht;
probe_ent->host_flags = pdc_port_info[board_idx].host_flags;
probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
......
......@@ -149,7 +149,8 @@ static struct ata_port_info sil_port_info[] = {
.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 @@ static struct ata_port_info sil_port_info[] = {
.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 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
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;
......
......@@ -230,7 +230,8 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
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;
......
......@@ -343,6 +343,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
* 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 */
......
......@@ -217,7 +217,8 @@ static struct ata_port_info pdc_port_info[] = {
.sht = &pdc_sata_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 = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &pdc_20621_ops,
},
......@@ -1384,6 +1385,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent->sht = pdc_port_info[board_idx].sht;
probe_ent->host_flags = pdc_port_info[board_idx].host_flags;
probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
probe_ent->mwdma_mask = pdc_port_info[board_idx].mwdma_mask;
probe_ent->udma_mask = pdc_port_info[board_idx].udma_mask;
probe_ent->port_ops = pdc_port_info[board_idx].port_ops;
......
......@@ -214,6 +214,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
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);
......
......@@ -320,6 +320,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
* 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 */
......
......@@ -42,6 +42,7 @@ enum {
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 @@ enum {
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),
......
......@@ -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 */
......@@ -140,6 +139,13 @@ enum {
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 +194,7 @@ struct ata_probe_ent {
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;
......@@ -252,7 +259,9 @@ struct ata_device {
unsigned int devno; /* 0 or 1 */
u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
unsigned int pio_mode;
unsigned int udma_mode;
unsigned int dma_mode;
unsigned int xfer_mode;
unsigned int xfer_shift; /* ATA_SHIFT_xxx */
/* cache info about current transfer mode */
u8 xfer_protocol; /* taskfile xfer protocol */
......@@ -277,6 +286,7 @@ struct ata_port {
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 +313,8 @@ struct ata_port_operations {
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 +350,7 @@ struct ata_port_info {
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;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment