|
@@ -62,7 +62,9 @@
|
|
|
#include "libata.h"
|
|
|
|
|
|
static unsigned int ata_dev_init_params(struct ata_port *ap,
|
|
|
- struct ata_device *dev);
|
|
|
+ struct ata_device *dev,
|
|
|
+ u16 heads,
|
|
|
+ u16 sectors);
|
|
|
static void ata_set_mode(struct ata_port *ap);
|
|
|
static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
|
|
|
struct ata_device *dev);
|
|
@@ -1081,9 +1083,8 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
|
|
|
*
|
|
|
* Read ID data from the specified device. ATA_CMD_ID_ATA is
|
|
|
* performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
|
|
|
- * devices. This function also takes care of EDD signature
|
|
|
- * misreporting (to be removed once EDD support is gone) and
|
|
|
- * issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives.
|
|
|
+ * devices. This function also issues ATA_CMD_INIT_DEV_PARAMS
|
|
|
+ * for pre-ATA4 drives.
|
|
|
*
|
|
|
* LOCKING:
|
|
|
* Kernel thread context (may sleep)
|
|
@@ -1095,7 +1096,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
|
|
|
unsigned int *p_class, int post_reset, u16 **p_id)
|
|
|
{
|
|
|
unsigned int class = *p_class;
|
|
|
- unsigned int using_edd;
|
|
|
struct ata_taskfile tf;
|
|
|
unsigned int err_mask = 0;
|
|
|
u16 *id;
|
|
@@ -1104,12 +1104,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
|
|
|
|
|
|
DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
|
|
|
|
|
|
- if (ap->ops->probe_reset ||
|
|
|
- ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
|
|
|
- using_edd = 0;
|
|
|
- else
|
|
|
- using_edd = 1;
|
|
|
-
|
|
|
ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
|
|
|
|
|
|
id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
|
|
@@ -1139,39 +1133,16 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
|
|
|
|
|
|
err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
|
|
|
id, sizeof(id[0]) * ATA_ID_WORDS);
|
|
|
-
|
|
|
if (err_mask) {
|
|
|
rc = -EIO;
|
|
|
reason = "I/O error";
|
|
|
-
|
|
|
- if (err_mask & ~AC_ERR_DEV)
|
|
|
- goto err_out;
|
|
|
-
|
|
|
- /*
|
|
|
- * arg! EDD works for all test cases, but seems to return
|
|
|
- * the ATA signature for some ATAPI devices. Until the
|
|
|
- * reason for this is found and fixed, we fix up the mess
|
|
|
- * here. If IDENTIFY DEVICE returns command aborted
|
|
|
- * (as ATAPI devices do), then we issue an
|
|
|
- * IDENTIFY PACKET DEVICE.
|
|
|
- *
|
|
|
- * ATA software reset (SRST, the default) does not appear
|
|
|
- * to have this problem.
|
|
|
- */
|
|
|
- if ((using_edd) && (class == ATA_DEV_ATA)) {
|
|
|
- u8 err = tf.feature;
|
|
|
- if (err & ATA_ABORTED) {
|
|
|
- class = ATA_DEV_ATAPI;
|
|
|
- goto retry;
|
|
|
- }
|
|
|
- }
|
|
|
goto err_out;
|
|
|
}
|
|
|
|
|
|
swap_buf_le16(id, ATA_ID_WORDS);
|
|
|
|
|
|
/* sanity check */
|
|
|
- if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) {
|
|
|
+ if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) {
|
|
|
rc = -EINVAL;
|
|
|
reason = "device reports illegal type";
|
|
|
goto err_out;
|
|
@@ -1187,7 +1158,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
|
|
|
* Some drives were very specific about that exact sequence.
|
|
|
*/
|
|
|
if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
|
|
|
- err_mask = ata_dev_init_params(ap, dev);
|
|
|
+ err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
|
|
|
if (err_mask) {
|
|
|
rc = -EIO;
|
|
|
reason = "INIT_DEV_PARAMS failed";
|
|
@@ -1440,7 +1411,11 @@ static int ata_bus_probe(struct ata_port *ap)
|
|
|
if (!found)
|
|
|
goto err_out_disable;
|
|
|
|
|
|
- ata_set_mode(ap);
|
|
|
+ if (ap->ops->set_mode)
|
|
|
+ ap->ops->set_mode(ap);
|
|
|
+ else
|
|
|
+ ata_set_mode(ap);
|
|
|
+
|
|
|
if (ap->flags & ATA_FLAG_PORT_DISABLED)
|
|
|
goto err_out_disable;
|
|
|
|
|
@@ -1845,7 +1820,7 @@ static void ata_host_set_dma(struct ata_port *ap)
|
|
|
*/
|
|
|
static void ata_set_mode(struct ata_port *ap)
|
|
|
{
|
|
|
- int i, rc;
|
|
|
+ int i, rc, used_dma = 0;
|
|
|
|
|
|
/* step 1: calculate xfer_mask */
|
|
|
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
|
@@ -1863,6 +1838,9 @@ static void ata_set_mode(struct ata_port *ap)
|
|
|
dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
|
|
|
dev->pio_mode = ata_xfer_mask2mode(pio_mask);
|
|
|
dev->dma_mode = ata_xfer_mask2mode(dma_mask);
|
|
|
+
|
|
|
+ if (dev->dma_mode)
|
|
|
+ used_dma = 1;
|
|
|
}
|
|
|
|
|
|
/* step 2: always set host PIO timings */
|
|
@@ -1884,6 +1862,17 @@ static void ata_set_mode(struct ata_port *ap)
|
|
|
goto err_out;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Record simplex status. If we selected DMA then the other
|
|
|
+ * host channels are not permitted to do so.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX))
|
|
|
+ ap->host_set->simplex_claimed = 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Chip specific finalisation
|
|
|
+ */
|
|
|
if (ap->ops->post_set_mode)
|
|
|
ap->ops->post_set_mode(ap);
|
|
|
|
|
@@ -2005,45 +1994,6 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
|
|
|
ap->ops->dev_select(ap, 0);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
|
|
|
- * @ap: Port to reset and probe
|
|
|
- *
|
|
|
- * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
|
|
|
- * probe the bus. Not often used these days.
|
|
|
- *
|
|
|
- * LOCKING:
|
|
|
- * PCI/etc. bus probe sem.
|
|
|
- * Obtains host_set lock.
|
|
|
- *
|
|
|
- */
|
|
|
-
|
|
|
-static unsigned int ata_bus_edd(struct ata_port *ap)
|
|
|
-{
|
|
|
- struct ata_taskfile tf;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- /* set up execute-device-diag (bus reset) taskfile */
|
|
|
- /* also, take interrupts to a known state (disabled) */
|
|
|
- DPRINTK("execute-device-diag\n");
|
|
|
- ata_tf_init(ap, &tf, 0);
|
|
|
- tf.ctl |= ATA_NIEN;
|
|
|
- tf.command = ATA_CMD_EDD;
|
|
|
- tf.protocol = ATA_PROT_NODATA;
|
|
|
-
|
|
|
- /* do bus reset */
|
|
|
- spin_lock_irqsave(&ap->host_set->lock, flags);
|
|
|
- ata_tf_to_host(ap, &tf);
|
|
|
- spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
|
|
-
|
|
|
- /* spec says at least 2ms. but who knows with those
|
|
|
- * crazy ATAPI devices...
|
|
|
- */
|
|
|
- msleep(150);
|
|
|
-
|
|
|
- return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
|
|
-}
|
|
|
-
|
|
|
static unsigned int ata_bus_softreset(struct ata_port *ap,
|
|
|
unsigned int devmask)
|
|
|
{
|
|
@@ -2078,13 +2028,12 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
|
|
|
*/
|
|
|
msleep(150);
|
|
|
|
|
|
-
|
|
|
/* Before we perform post reset processing we want to see if
|
|
|
- the bus shows 0xFF because the odd clown forgets the D7 pulldown
|
|
|
- resistor */
|
|
|
-
|
|
|
+ * the bus shows 0xFF because the odd clown forgets the D7
|
|
|
+ * pulldown resistor.
|
|
|
+ */
|
|
|
if (ata_check_status(ap) == 0xFF)
|
|
|
- return 1; /* Positive is failure for some reason */
|
|
|
+ return AC_ERR_OTHER;
|
|
|
|
|
|
ata_bus_post_reset(ap, devmask);
|
|
|
|
|
@@ -2116,7 +2065,7 @@ void ata_bus_reset(struct ata_port *ap)
|
|
|
struct ata_ioports *ioaddr = &ap->ioaddr;
|
|
|
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
|
|
|
u8 err;
|
|
|
- unsigned int dev0, dev1 = 0, rc = 0, devmask = 0;
|
|
|
+ unsigned int dev0, dev1 = 0, devmask = 0;
|
|
|
|
|
|
DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
|
|
|
|
|
@@ -2139,18 +2088,8 @@ void ata_bus_reset(struct ata_port *ap)
|
|
|
|
|
|
/* issue bus reset */
|
|
|
if (ap->flags & ATA_FLAG_SRST)
|
|
|
- rc = ata_bus_softreset(ap, devmask);
|
|
|
- else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) {
|
|
|
- /* set up device control */
|
|
|
- if (ap->flags & ATA_FLAG_MMIO)
|
|
|
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
|
|
|
- else
|
|
|
- outb(ap->ctl, ioaddr->ctl_addr);
|
|
|
- rc = ata_bus_edd(ap);
|
|
|
- }
|
|
|
-
|
|
|
- if (rc)
|
|
|
- goto err_out;
|
|
|
+ if (ata_bus_softreset(ap, devmask))
|
|
|
+ goto err_out;
|
|
|
|
|
|
/*
|
|
|
* determine by signature whether we have ATA or ATAPI devices
|
|
@@ -2223,9 +2162,9 @@ static int sata_phy_resume(struct ata_port *ap)
|
|
|
* so makes reset sequence different from the original
|
|
|
* ->phy_reset implementation and Jeff nervous. :-P
|
|
|
*/
|
|
|
-extern void ata_std_probeinit(struct ata_port *ap)
|
|
|
+void ata_std_probeinit(struct ata_port *ap)
|
|
|
{
|
|
|
- if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) {
|
|
|
+ if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
|
|
|
sata_phy_resume(ap);
|
|
|
if (sata_dev_present(ap))
|
|
|
ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
|
|
@@ -2714,18 +2653,23 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
|
|
|
* known limits including host controller limits, device
|
|
|
* blacklist, etc...
|
|
|
*
|
|
|
+ * FIXME: The current implementation limits all transfer modes to
|
|
|
+ * the fastest of the lowested device on the port. This is not
|
|
|
+ * required on most controllers.
|
|
|
+ *
|
|
|
* LOCKING:
|
|
|
* None.
|
|
|
*/
|
|
|
static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
|
|
|
{
|
|
|
+ struct ata_host_set *hs = ap->host_set;
|
|
|
unsigned long xfer_mask;
|
|
|
int i;
|
|
|
|
|
|
xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
|
|
|
ap->udma_mask);
|
|
|
|
|
|
- /* use port-wide xfermask for now */
|
|
|
+ /* FIXME: Use port-wide xfermask for now */
|
|
|
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
|
|
struct ata_device *d = &ap->device[i];
|
|
|
if (!ata_dev_present(d))
|
|
@@ -2735,12 +2679,23 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
|
|
|
xfer_mask &= ata_id_xfermask(d->id);
|
|
|
if (ata_dma_blacklisted(d))
|
|
|
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
|
|
|
+ /* Apply cable rule here. Don't apply it early because when
|
|
|
+ we handle hot plug the cable type can itself change */
|
|
|
+ if (ap->cbl == ATA_CBL_PATA40)
|
|
|
+ xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
|
|
|
}
|
|
|
|
|
|
if (ata_dma_blacklisted(dev))
|
|
|
printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
|
|
|
"disabling DMA\n", ap->id, dev->devno);
|
|
|
|
|
|
+ if (hs->flags & ATA_HOST_SIMPLEX) {
|
|
|
+ if (hs->simplex_claimed)
|
|
|
+ xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
|
|
|
+ }
|
|
|
+ if (ap->ops->mode_filter)
|
|
|
+ xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
|
|
|
+
|
|
|
ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
|
|
|
&dev->udma_mask);
|
|
|
}
|
|
@@ -2795,16 +2750,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
|
|
|
*/
|
|
|
|
|
|
static unsigned int ata_dev_init_params(struct ata_port *ap,
|
|
|
- struct ata_device *dev)
|
|
|
+ struct ata_device *dev,
|
|
|
+ u16 heads,
|
|
|
+ u16 sectors)
|
|
|
{
|
|
|
struct ata_taskfile tf;
|
|
|
unsigned int err_mask;
|
|
|
- u16 sectors = dev->id[6];
|
|
|
- u16 heads = dev->id[3];
|
|
|
|
|
|
/* Number of sectors per track 1-255. Number of heads 1-16 */
|
|
|
if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
|
|
|
- return 0;
|
|
|
+ return AC_ERR_INVALID;
|
|
|
|
|
|
/* set up init dev params taskfile */
|
|
|
DPRINTK("init dev params \n");
|
|
@@ -4536,6 +4491,14 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
|
|
|
int rc;
|
|
|
|
|
|
DPRINTK("ENTER\n");
|
|
|
+
|
|
|
+ if (!ent->port_ops->probe_reset &&
|
|
|
+ !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
|
|
|
+ printk(KERN_ERR "ata%u: no reset mechanism available\n",
|
|
|
+ port_no);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
host = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
|
|
|
if (!host)
|
|
|
return NULL;
|
|
@@ -4596,6 +4559,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
|
|
|
host_set->mmio_base = ent->mmio_base;
|
|
|
host_set->private_data = ent->private_data;
|
|
|
host_set->ops = ent->port_ops;
|
|
|
+ host_set->flags = ent->host_set_flags;
|
|
|
|
|
|
/* register each port bound to this device */
|
|
|
for (i = 0; i < ent->n_ports; i++) {
|