X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fscsi%2Flibata-core.c;h=249e67fab81f2567b32c367d8db0ccf94b75dcad;hb=cac925a4aab1b7233d3beb591f53498816058a08;hp=902c76364af7fb01e6265318cc69b92a62def2ff;hpb=644dd0cc494702ecd0698f467de113ace9593888;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 902c763..b046ffa 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -48,9 +48,11 @@ #include #include #include +#include +#include #include -#include "scsi.h" #include "scsi_priv.h" +#include #include #include #include @@ -59,1285 +61,1283 @@ #include "libata.h" -static unsigned int ata_busy_sleep (struct ata_port *ap, - unsigned long tmout_pat, - unsigned long tmout); +static unsigned int ata_dev_init_params(struct ata_port *ap, + struct ata_device *dev, + u16 heads, + u16 sectors); 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(u32 bitmap); -static int ata_choose_xfer_mode(struct ata_port *ap, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out); -static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); -static void __ata_qc_complete(struct ata_queued_cmd *qc); +static unsigned int ata_dev_set_xfermode(struct ata_port *ap, + struct ata_device *dev); +static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev); static unsigned int ata_unique_id = 1; static struct workqueue_struct *ata_wq; -int atapi_enabled = 0; +int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); +int libata_fua = 0; +module_param_named(fua, libata_fua, int, 0444); +MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); + MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); + /** - * ata_tf_load - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set + * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure + * @tf: Taskfile to convert + * @fis: Buffer into which data will output + * @pmp: Port multiplier port * - * Outputs ATA taskfile to standard ATA host controller. + * Converts a standard ATA taskfile to a Serial ATA + * FIS structure (Register - Host to Device). * * LOCKING: * Inherited from caller. */ -static void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf) +void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) { - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - - if (tf->ctl != ap->last_ctl) { - outb(tf->ctl, ioaddr->ctl_addr); - ap->last_ctl = tf->ctl; - ata_wait_idle(ap); - } + fis[0] = 0x27; /* Register - Host to Device FIS */ + fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number, + bit 7 indicates Command FIS */ + fis[2] = tf->command; + fis[3] = tf->feature; - if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - outb(tf->hob_feature, ioaddr->feature_addr); - outb(tf->hob_nsect, ioaddr->nsect_addr); - outb(tf->hob_lbal, ioaddr->lbal_addr); - outb(tf->hob_lbam, ioaddr->lbam_addr); - outb(tf->hob_lbah, ioaddr->lbah_addr); - VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", - tf->hob_feature, - tf->hob_nsect, - tf->hob_lbal, - tf->hob_lbam, - tf->hob_lbah); - } + fis[4] = tf->lbal; + fis[5] = tf->lbam; + fis[6] = tf->lbah; + fis[7] = tf->device; - if (is_addr) { - outb(tf->feature, ioaddr->feature_addr); - outb(tf->nsect, ioaddr->nsect_addr); - outb(tf->lbal, ioaddr->lbal_addr); - outb(tf->lbam, ioaddr->lbam_addr); - outb(tf->lbah, ioaddr->lbah_addr); - VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", - tf->feature, - tf->nsect, - tf->lbal, - tf->lbam, - tf->lbah); - } + fis[8] = tf->hob_lbal; + fis[9] = tf->hob_lbam; + fis[10] = tf->hob_lbah; + fis[11] = tf->hob_feature; - if (tf->flags & ATA_TFLAG_DEVICE) { - outb(tf->device, ioaddr->device_addr); - VPRINTK("device 0x%X\n", tf->device); - } + fis[12] = tf->nsect; + fis[13] = tf->hob_nsect; + fis[14] = 0; + fis[15] = tf->ctl; - ata_wait_idle(ap); + fis[16] = 0; + fis[17] = 0; + fis[18] = 0; + fis[19] = 0; } /** - * ata_tf_load_mmio - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set + * ata_tf_from_fis - Convert SATA FIS to ATA taskfile + * @fis: Buffer from which data will be input + * @tf: Taskfile to output * - * Outputs ATA taskfile to standard ATA host controller using MMIO. + * Converts a serial ATA FIS structure to a standard ATA taskfile. * * LOCKING: * Inherited from caller. */ -static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) +void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) { - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; - - if (tf->ctl != ap->last_ctl) { - writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); - ap->last_ctl = tf->ctl; - ata_wait_idle(ap); - } - - if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { - writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); - writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); - writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); - writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); - writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); - VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", - tf->hob_feature, - tf->hob_nsect, - tf->hob_lbal, - tf->hob_lbam, - tf->hob_lbah); - } + tf->command = fis[2]; /* status */ + tf->feature = fis[3]; /* error */ - if (is_addr) { - writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); - writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); - writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); - writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); - writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); - VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", - tf->feature, - tf->nsect, - tf->lbal, - tf->lbam, - tf->lbah); - } + tf->lbal = fis[4]; + tf->lbam = fis[5]; + tf->lbah = fis[6]; + tf->device = fis[7]; - if (tf->flags & ATA_TFLAG_DEVICE) { - writeb(tf->device, (void __iomem *) ioaddr->device_addr); - VPRINTK("device 0x%X\n", tf->device); - } + tf->hob_lbal = fis[8]; + tf->hob_lbam = fis[9]; + tf->hob_lbah = fis[10]; - ata_wait_idle(ap); + tf->nsect = fis[12]; + tf->hob_nsect = fis[13]; } +static const u8 ata_rw_cmds[] = { + /* pio multi */ + ATA_CMD_READ_MULTI, + ATA_CMD_WRITE_MULTI, + ATA_CMD_READ_MULTI_EXT, + ATA_CMD_WRITE_MULTI_EXT, + 0, + 0, + 0, + ATA_CMD_WRITE_MULTI_FUA_EXT, + /* pio */ + ATA_CMD_PIO_READ, + ATA_CMD_PIO_WRITE, + ATA_CMD_PIO_READ_EXT, + ATA_CMD_PIO_WRITE_EXT, + 0, + 0, + 0, + 0, + /* dma */ + ATA_CMD_READ, + ATA_CMD_WRITE, + ATA_CMD_READ_EXT, + ATA_CMD_WRITE_EXT, + 0, + 0, + 0, + ATA_CMD_WRITE_FUA_EXT +}; /** - * ata_tf_load - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Outputs ATA taskfile to standard ATA host controller using MMIO - * or PIO as indicated by the ATA_FLAG_MMIO flag. - * Writes the control, feature, nsect, lbal, lbam, and lbah registers. - * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, - * hob_lbal, hob_lbam, and hob_lbah. - * - * This function waits for idle (!BUSY and !DRQ) after writing - * registers. If the control register has a new value, this - * function also waits for idle after writing control and before - * writing the remaining registers. + * ata_rwcmd_protocol - set taskfile r/w commands and protocol + * @qc: command to examine and configure * - * May be used as the tf_load() entry in ata_port_operations. + * Examine the device configuration and tf->flags to calculate + * the proper read/write commands and protocol to use. * * LOCKING: - * Inherited from caller. + * caller. */ -void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) +int ata_rwcmd_protocol(struct ata_queued_cmd *qc) { - if (ap->flags & ATA_FLAG_MMIO) - ata_tf_load_mmio(ap, tf); - else - ata_tf_load_pio(ap, tf); + struct ata_taskfile *tf = &qc->tf; + struct ata_device *dev = qc->dev; + u8 cmd; + + int index, fua, lba48, write; + + fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0; + lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0; + write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0; + + if (dev->flags & ATA_DFLAG_PIO) { + tf->protocol = ATA_PROT_PIO; + index = dev->multi_count ? 0 : 8; + } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { + /* Unable to use DMA due to host limitation */ + tf->protocol = ATA_PROT_PIO; + index = dev->multi_count ? 0 : 8; + } else { + tf->protocol = ATA_PROT_DMA; + index = 16; + } + + cmd = ata_rw_cmds[index + fua + lba48 + write]; + if (cmd) { + tf->command = cmd; + return 0; + } + return -1; } /** - * ata_exec_command_pio - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set + * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask + * @pio_mask: pio_mask + * @mwdma_mask: mwdma_mask + * @udma_mask: udma_mask * - * Issues PIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. + * Pack @pio_mask, @mwdma_mask and @udma_mask into a single + * unsigned int xfer_mask. * * LOCKING: - * spin_lock_irqsave(host_set lock) + * None. + * + * RETURNS: + * Packed xfer_mask. */ - -static void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf) +static unsigned int ata_pack_xfermask(unsigned int pio_mask, + unsigned int mwdma_mask, + unsigned int udma_mask) { - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - - outb(tf->command, ap->ioaddr.command_addr); - ata_pause(ap); + return ((pio_mask << ATA_SHIFT_PIO) & ATA_MASK_PIO) | + ((mwdma_mask << ATA_SHIFT_MWDMA) & ATA_MASK_MWDMA) | + ((udma_mask << ATA_SHIFT_UDMA) & ATA_MASK_UDMA); } - /** - * ata_exec_command_mmio - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) + * ata_unpack_xfermask - Unpack xfer_mask into pio, mwdma and udma masks + * @xfer_mask: xfer_mask to unpack + * @pio_mask: resulting pio_mask + * @mwdma_mask: resulting mwdma_mask + * @udma_mask: resulting udma_mask + * + * Unpack @xfer_mask into @pio_mask, @mwdma_mask and @udma_mask. + * Any NULL distination masks will be ignored. */ - -static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) +static void ata_unpack_xfermask(unsigned int xfer_mask, + unsigned int *pio_mask, + unsigned int *mwdma_mask, + unsigned int *udma_mask) { - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - - writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); - ata_pause(ap); + if (pio_mask) + *pio_mask = (xfer_mask & ATA_MASK_PIO) >> ATA_SHIFT_PIO; + if (mwdma_mask) + *mwdma_mask = (xfer_mask & ATA_MASK_MWDMA) >> ATA_SHIFT_MWDMA; + if (udma_mask) + *udma_mask = (xfer_mask & ATA_MASK_UDMA) >> ATA_SHIFT_UDMA; } +static const struct ata_xfer_ent { + int shift, bits; + u8 base; +} ata_xfer_tbl[] = { + { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, + { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, + { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, + { -1, }, +}; /** - * ata_exec_command - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set + * ata_xfer_mask2mode - Find matching XFER_* for the given xfer_mask + * @xfer_mask: xfer_mask of interest * - * Issues PIO/MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. + * Return matching XFER_* value for @xfer_mask. Only the highest + * bit of @xfer_mask is considered. * * LOCKING: - * spin_lock_irqsave(host_set lock) + * None. + * + * RETURNS: + * Matching XFER_* value, 0 if no match found. */ -void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf) +static u8 ata_xfer_mask2mode(unsigned int xfer_mask) { - if (ap->flags & ATA_FLAG_MMIO) - ata_exec_command_mmio(ap, tf); - else - ata_exec_command_pio(ap, tf); + int highbit = fls(xfer_mask) - 1; + const struct ata_xfer_ent *ent; + + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (highbit >= ent->shift && highbit < ent->shift + ent->bits) + return ent->base + highbit - ent->shift; + return 0; } /** - * ata_exec - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set + * ata_xfer_mode2mask - Find matching xfer_mask for XFER_* + * @xfer_mode: XFER_* of interest * - * Issues PIO/MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. + * Return matching xfer_mask for @xfer_mode. * * LOCKING: - * Obtains host_set lock. + * None. + * + * RETURNS: + * Matching xfer_mask, 0 if no match found. */ - -static inline void ata_exec(struct ata_port *ap, struct ata_taskfile *tf) +static unsigned int ata_xfer_mode2mask(u8 xfer_mode) { - unsigned long flags; + const struct ata_xfer_ent *ent; - DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->ops->exec_command(ap, tf); - spin_unlock_irqrestore(&ap->host_set->lock, flags); + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) + return 1 << (ent->shift + xfer_mode - ent->base); + return 0; } /** - * ata_tf_to_host - issue ATA taskfile to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set + * ata_xfer_mode2shift - Find matching xfer_shift for XFER_* + * @xfer_mode: XFER_* of interest * - * Issues ATA taskfile register set to ATA host controller, - * with proper synchronization with interrupt handler and - * other threads. + * Return matching xfer_shift for @xfer_mode. * * LOCKING: - * Obtains host_set lock. + * None. + * + * RETURNS: + * Matching xfer_shift, -1 if no match found. */ - -static void ata_tf_to_host(struct ata_port *ap, struct ata_taskfile *tf) +static int ata_xfer_mode2shift(unsigned int xfer_mode) { - ap->ops->tf_load(ap, tf); + const struct ata_xfer_ent *ent; - ata_exec(ap, tf); + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (xfer_mode >= ent->base && xfer_mode < ent->base + ent->bits) + return ent->shift; + return -1; } /** - * ata_tf_to_host_nolock - issue ATA taskfile to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set + * ata_mode_string - convert xfer_mask to string + * @xfer_mask: mask of bits supported; only highest bit counts. * - * Issues ATA taskfile register set to ATA host controller, - * with proper synchronization with interrupt handler and - * other threads. + * Determine string which represents the highest speed + * (highest bit in @modemask). * * LOCKING: - * spin_lock_irqsave(host_set lock) + * None. + * + * RETURNS: + * Constant C string representing highest speed listed in + * @mode_mask, or the constant C string "". */ +static const char *ata_mode_string(unsigned int xfer_mask) +{ + static const char * const xfer_mode_str[] = { + "PIO0", + "PIO1", + "PIO2", + "PIO3", + "PIO4", + "MWDMA0", + "MWDMA1", + "MWDMA2", + "UDMA/16", + "UDMA/25", + "UDMA/33", + "UDMA/44", + "UDMA/66", + "UDMA/100", + "UDMA/133", + "UDMA7", + }; + int highbit; + + highbit = fls(xfer_mask) - 1; + if (highbit >= 0 && highbit < ARRAY_SIZE(xfer_mode_str)) + return xfer_mode_str[highbit]; + return ""; +} -void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf) +static void ata_dev_disable(struct ata_port *ap, struct ata_device *dev) { - ap->ops->tf_load(ap, tf); - ap->ops->exec_command(ap, tf); + if (ata_dev_present(dev)) { + printk(KERN_WARNING "ata%u: dev %u disabled\n", + ap->id, dev->devno); + dev->class++; + } } /** - * ata_tf_read_pio - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input + * ata_pio_devchk - PATA device presence detection + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) * - * Reads ATA taskfile registers for currently-selected device - * into @tf. + * This technique was originally described in + * Hale Landis's ATADRVR (www.ata-atapi.com), and + * later found its way into the ATA/ATAPI spec. + * + * Write a pattern to the ATA shadow registers, + * and if a device is present, it will respond by + * correctly storing and echoing back the + * ATA shadow register contents. * * LOCKING: - * Inherited from caller. + * caller. */ -static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) +static unsigned int ata_pio_devchk(struct ata_port *ap, + unsigned int device) { struct ata_ioports *ioaddr = &ap->ioaddr; + u8 nsect, lbal; - tf->nsect = inb(ioaddr->nsect_addr); - tf->lbal = inb(ioaddr->lbal_addr); - tf->lbam = inb(ioaddr->lbam_addr); - tf->lbah = inb(ioaddr->lbah_addr); - tf->device = inb(ioaddr->device_addr); - - if (tf->flags & ATA_TFLAG_LBA48) { - outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); - tf->hob_feature = inb(ioaddr->error_addr); - tf->hob_nsect = inb(ioaddr->nsect_addr); - tf->hob_lbal = inb(ioaddr->lbal_addr); - tf->hob_lbam = inb(ioaddr->lbam_addr); - tf->hob_lbah = inb(ioaddr->lbah_addr); - } + ap->ops->dev_select(ap, device); + + outb(0x55, ioaddr->nsect_addr); + outb(0xaa, ioaddr->lbal_addr); + + outb(0xaa, ioaddr->nsect_addr); + outb(0x55, ioaddr->lbal_addr); + + outb(0x55, ioaddr->nsect_addr); + outb(0xaa, ioaddr->lbal_addr); + + nsect = inb(ioaddr->nsect_addr); + lbal = inb(ioaddr->lbal_addr); + + if ((nsect == 0x55) && (lbal == 0xaa)) + return 1; /* we found a device */ + + return 0; /* nothing found */ } /** - * ata_tf_read_mmio - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input + * ata_mmio_devchk - PATA device presence detection + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) + * + * This technique was originally described in + * Hale Landis's ATADRVR (www.ata-atapi.com), and + * later found its way into the ATA/ATAPI spec. * - * Reads ATA taskfile registers for currently-selected device - * into @tf via MMIO. + * Write a pattern to the ATA shadow registers, + * and if a device is present, it will respond by + * correctly storing and echoing back the + * ATA shadow register contents. * * LOCKING: - * Inherited from caller. + * caller. */ -static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) +static unsigned int ata_mmio_devchk(struct ata_port *ap, + unsigned int device) { struct ata_ioports *ioaddr = &ap->ioaddr; + u8 nsect, lbal; - tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); - tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); - tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); - tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); - tf->device = readb((void __iomem *)ioaddr->device_addr); - - if (tf->flags & ATA_TFLAG_LBA48) { - writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); - tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); - tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); - tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); - tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); - tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); - } -} + ap->ops->dev_select(ap, device); + writeb(0x55, (void __iomem *) ioaddr->nsect_addr); + writeb(0xaa, (void __iomem *) ioaddr->lbal_addr); -/** - * ata_tf_read - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Reads ATA taskfile registers for currently-selected device - * into @tf. - * - * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 - * is set, also reads the hob registers. - * - * May be used as the tf_read() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - if (ap->flags & ATA_FLAG_MMIO) - ata_tf_read_mmio(ap, tf); - else - ata_tf_read_pio(ap, tf); + writeb(0xaa, (void __iomem *) ioaddr->nsect_addr); + writeb(0x55, (void __iomem *) ioaddr->lbal_addr); + + writeb(0x55, (void __iomem *) ioaddr->nsect_addr); + writeb(0xaa, (void __iomem *) ioaddr->lbal_addr); + + nsect = readb((void __iomem *) ioaddr->nsect_addr); + lbal = readb((void __iomem *) ioaddr->lbal_addr); + + if ((nsect == 0x55) && (lbal == 0xaa)) + return 1; /* we found a device */ + + return 0; /* nothing found */ } /** - * ata_check_status_pio - Read device status reg & clear interrupt - * @ap: port where the device is + * ata_devchk - PATA device presence detection + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) * - * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts - * from this device + * Dispatch ATA device presence detection, depending + * on whether we are using PIO or MMIO to talk to the + * ATA shadow registers. * * LOCKING: - * Inherited from caller. + * caller. */ -static u8 ata_check_status_pio(struct ata_port *ap) + +static unsigned int ata_devchk(struct ata_port *ap, + unsigned int device) { - return inb(ap->ioaddr.status_addr); + if (ap->flags & ATA_FLAG_MMIO) + return ata_mmio_devchk(ap, device); + return ata_pio_devchk(ap, device); } /** - * ata_check_status_mmio - Read device status reg & clear interrupt - * @ap: port where the device is + * ata_dev_classify - determine device type based on ATA-spec signature + * @tf: ATA taskfile register set for device to be identified * - * Reads ATA taskfile status register for currently-selected device - * via MMIO and return its value. This also clears pending interrupts - * from this device + * Determine from taskfile register contents whether a device is + * ATA or ATAPI, as per "Signature and persistence" section + * of ATA/PI spec (volume 1, sect 5.14). * * LOCKING: - * Inherited from caller. + * None. + * + * RETURNS: + * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, or %ATA_DEV_UNKNOWN + * the event of failure. */ -static u8 ata_check_status_mmio(struct ata_port *ap) -{ - return readb((void __iomem *) ap->ioaddr.status_addr); -} +unsigned int ata_dev_classify(const struct ata_taskfile *tf) +{ + /* Apple's open source Darwin code hints that some devices only + * put a proper signature into the LBA mid/high registers, + * So, we only check those. It's sufficient for uniqueness. + */ + + if (((tf->lbam == 0) && (tf->lbah == 0)) || + ((tf->lbam == 0x3c) && (tf->lbah == 0xc3))) { + DPRINTK("found ATA device by sig\n"); + return ATA_DEV_ATA; + } + + if (((tf->lbam == 0x14) && (tf->lbah == 0xeb)) || + ((tf->lbam == 0x69) && (tf->lbah == 0x96))) { + DPRINTK("found ATAPI device by sig\n"); + return ATA_DEV_ATAPI; + } + + DPRINTK("unknown device\n"); + return ATA_DEV_UNKNOWN; +} /** - * ata_check_status - Read device status reg & clear interrupt - * @ap: port where the device is + * ata_dev_try_classify - Parse returned ATA device signature + * @ap: ATA channel to examine + * @device: Device to examine (starting at zero) + * @r_err: Value of error register on completion * - * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts - * from this device + * After an event -- SRST, E.D.D., or SATA COMRESET -- occurs, + * an ATA/ATAPI-defined set of values is placed in the ATA + * shadow registers, indicating the results of device detection + * and diagnostics. * - * May be used as the check_status() entry in ata_port_operations. + * Select the ATA device, and read the values from the ATA shadow + * registers. Then parse according to the Error register value, + * and the spec-defined values examined by ata_dev_classify(). * * LOCKING: - * Inherited from caller. + * caller. + * + * RETURNS: + * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE. */ -u8 ata_check_status(struct ata_port *ap) + +static unsigned int +ata_dev_try_classify(struct ata_port *ap, unsigned int device, u8 *r_err) { - if (ap->flags & ATA_FLAG_MMIO) - return ata_check_status_mmio(ap); - return ata_check_status_pio(ap); -} + struct ata_taskfile tf; + unsigned int class; + u8 err; + + ap->ops->dev_select(ap, device); + + memset(&tf, 0, sizeof(tf)); + + ap->ops->tf_read(ap, &tf); + err = tf.feature; + if (r_err) + *r_err = err; + + /* see if device passed diags */ + if (err == 1) + /* do nothing */ ; + else if ((device == 0) && (err == 0x81)) + /* do nothing */ ; + else + return ATA_DEV_NONE; + + /* determine if device is ATA or ATAPI */ + class = ata_dev_classify(&tf); + if (class == ATA_DEV_UNKNOWN) + return ATA_DEV_NONE; + if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0)) + return ATA_DEV_NONE; + return class; +} /** - * ata_altstatus - Read device alternate status reg - * @ap: port where the device is - * - * Reads ATA taskfile alternate status register for - * currently-selected device and return its value. + * ata_id_string - Convert IDENTIFY DEVICE page into string + * @id: IDENTIFY DEVICE results we will examine + * @s: string into which data is output + * @ofs: offset into identify device page + * @len: length of string to return. must be an even number. * - * Note: may NOT be used as the check_altstatus() entry in - * ata_port_operations. + * The strings in the IDENTIFY DEVICE page are broken up into + * 16-bit chunks. Run through the string, and output each + * 8-bit chunk linearly, regardless of platform. * * LOCKING: - * Inherited from caller. + * caller. */ -u8 ata_altstatus(struct ata_port *ap) + +void ata_id_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) { - if (ap->ops->check_altstatus) - return ap->ops->check_altstatus(ap); + unsigned int c; - if (ap->flags & ATA_FLAG_MMIO) - return readb((void __iomem *)ap->ioaddr.altstatus_addr); - return inb(ap->ioaddr.altstatus_addr); -} + while (len > 0) { + c = id[ofs] >> 8; + *s = c; + s++; + + c = id[ofs] & 0xff; + *s = c; + s++; + ofs++; + len -= 2; + } +} /** - * ata_chk_err - Read device error reg - * @ap: port where the device is - * - * Reads ATA taskfile error register for - * currently-selected device and return its value. + * ata_id_c_string - Convert IDENTIFY DEVICE page into C string + * @id: IDENTIFY DEVICE results we will examine + * @s: string into which data is output + * @ofs: offset into identify device page + * @len: length of string to return. must be an odd number. * - * Note: may NOT be used as the check_err() entry in - * ata_port_operations. + * This function is identical to ata_id_string except that it + * trims trailing spaces and terminates the resulting string with + * null. @len must be actual maximum length (even number) + 1. * * LOCKING: - * Inherited from caller. + * caller. */ -u8 ata_chk_err(struct ata_port *ap) +void ata_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) { - if (ap->ops->check_err) - return ap->ops->check_err(ap); + unsigned char *p; - if (ap->flags & ATA_FLAG_MMIO) { - return readb((void __iomem *) ap->ioaddr.error_addr); + WARN_ON(!(len & 1)); + + ata_id_string(id, s, ofs, len - 1); + + p = s + strnlen(s, len - 1); + while (p > s && p[-1] == ' ') + p--; + *p = '\0'; +} + +static u64 ata_id_n_sectors(const u16 *id) +{ + if (ata_id_has_lba(id)) { + if (ata_id_has_lba48(id)) + return ata_id_u64(id, 100); + else + return ata_id_u32(id, 60); + } else { + if (ata_id_current_chs_valid(id)) + return ata_id_u32(id, 57); + else + return id[1] * id[3] * id[6]; } - return inb(ap->ioaddr.error_addr); } /** - * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure - * @tf: Taskfile to convert - * @fis: Buffer into which data will output - * @pmp: Port multiplier port + * ata_noop_dev_select - Select device 0/1 on ATA bus + * @ap: ATA channel to manipulate + * @device: ATA device (numbered from zero) to select * - * Converts a standard ATA taskfile to a Serial ATA - * FIS structure (Register - Host to Device). + * This function performs no actual function. + * + * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: - * Inherited from caller. + * caller. */ - -void ata_tf_to_fis(struct ata_taskfile *tf, u8 *fis, u8 pmp) +void ata_noop_dev_select (struct ata_port *ap, unsigned int device) { - fis[0] = 0x27; /* Register - Host to Device FIS */ - fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number, - bit 7 indicates Command FIS */ - fis[2] = tf->command; - fis[3] = tf->feature; - - fis[4] = tf->lbal; - fis[5] = tf->lbam; - fis[6] = tf->lbah; - fis[7] = tf->device; - - fis[8] = tf->hob_lbal; - fis[9] = tf->hob_lbam; - fis[10] = tf->hob_lbah; - fis[11] = tf->hob_feature; - - fis[12] = tf->nsect; - fis[13] = tf->hob_nsect; - fis[14] = 0; - fis[15] = tf->ctl; - - fis[16] = 0; - fis[17] = 0; - fis[18] = 0; - fis[19] = 0; } + /** - * ata_tf_from_fis - Convert SATA FIS to ATA taskfile - * @fis: Buffer from which data will be input - * @tf: Taskfile to output + * ata_std_dev_select - Select device 0/1 on ATA bus + * @ap: ATA channel to manipulate + * @device: ATA device (numbered from zero) to select * - * Converts a standard ATA taskfile to a Serial ATA - * FIS structure (Register - Host to Device). + * Use the method defined in the ATA specification to + * make either device 0, or device 1, active on the + * ATA channel. Works with both PIO and MMIO. + * + * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: - * Inherited from caller. + * caller. */ -void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf) +void ata_std_dev_select (struct ata_port *ap, unsigned int device) { - tf->command = fis[2]; /* status */ - tf->feature = fis[3]; /* error */ - - tf->lbal = fis[4]; - tf->lbam = fis[5]; - tf->lbah = fis[6]; - tf->device = fis[7]; + u8 tmp; - tf->hob_lbal = fis[8]; - tf->hob_lbam = fis[9]; - tf->hob_lbah = fis[10]; + if (device == 0) + tmp = ATA_DEVICE_OBS; + else + tmp = ATA_DEVICE_OBS | ATA_DEV1; - tf->nsect = fis[12]; - tf->hob_nsect = fis[13]; + if (ap->flags & ATA_FLAG_MMIO) { + writeb(tmp, (void __iomem *) ap->ioaddr.device_addr); + } else { + outb(tmp, ap->ioaddr.device_addr); + } + ata_pause(ap); /* needed; also flushes, for mmio */ } /** - * ata_prot_to_cmd - determine which read/write opcodes to use - * @protocol: ATA_PROT_xxx taskfile protocol - * @lba48: true is lba48 is present + * ata_dev_select - Select device 0/1 on ATA bus + * @ap: ATA channel to manipulate + * @device: ATA device (numbered from zero) to select + * @wait: non-zero to wait for Status register BSY bit to clear + * @can_sleep: non-zero if context allows sleeping + * + * Use the method defined in the ATA specification to + * make either device 0, or device 1, active on the + * ATA channel. * - * Given necessary input, determine which read/write commands - * to use to transfer data. + * This is a high-level version of ata_std_dev_select(), + * which additionally provides the services of inserting + * the proper pauses and status polling, where needed. * * LOCKING: - * None. + * caller. */ -static int ata_prot_to_cmd(int protocol, int lba48) + +void ata_dev_select(struct ata_port *ap, unsigned int device, + unsigned int wait, unsigned int can_sleep) { - int rcmd = 0, wcmd = 0; + VPRINTK("ENTER, ata%u: device %u, wait %u\n", + ap->id, device, wait); - switch (protocol) { - case ATA_PROT_PIO: - if (lba48) { - rcmd = ATA_CMD_PIO_READ_EXT; - wcmd = ATA_CMD_PIO_WRITE_EXT; - } else { - rcmd = ATA_CMD_PIO_READ; - wcmd = ATA_CMD_PIO_WRITE; - } - break; + if (wait) + ata_wait_idle(ap); - case ATA_PROT_DMA: - if (lba48) { - rcmd = ATA_CMD_READ_EXT; - wcmd = ATA_CMD_WRITE_EXT; - } else { - rcmd = ATA_CMD_READ; - wcmd = ATA_CMD_WRITE; - } - break; + ap->ops->dev_select(ap, device); - default: - return -1; + if (wait) { + if (can_sleep && ap->device[device].class == ATA_DEV_ATAPI) + msleep(150); + ata_wait_idle(ap); } - - return rcmd | (wcmd << 8); } /** - * ata_dev_set_protocol - set taskfile protocol and r/w commands - * @dev: device to examine and configure + * ata_dump_id - IDENTIFY DEVICE info debugging output + * @id: IDENTIFY DEVICE page to dump * - * Examine the device configuration, after we have - * read the identify-device page and configured the - * data transfer mode. Set internal state related to - * the ATA taskfile protocol (pio, pio mult, dma, etc.) - * and calculate the proper read/write commands to use. + * Dump selected 16-bit words from the given IDENTIFY DEVICE + * page. * * LOCKING: * caller. */ -static void ata_dev_set_protocol(struct ata_device *dev) -{ - int pio = (dev->flags & ATA_DFLAG_PIO); - int lba48 = (dev->flags & ATA_DFLAG_LBA48); - int proto, cmd; - - if (pio) - proto = dev->xfer_protocol = ATA_PROT_PIO; - else - proto = dev->xfer_protocol = ATA_PROT_DMA; - - cmd = ata_prot_to_cmd(proto, lba48); - if (cmd < 0) - BUG(); - dev->read_cmd = cmd & 0xff; - dev->write_cmd = (cmd >> 8) & 0xff; +static inline void ata_dump_id(const u16 *id) +{ + DPRINTK("49==0x%04x " + "53==0x%04x " + "63==0x%04x " + "64==0x%04x " + "75==0x%04x \n", + id[49], + id[53], + id[63], + id[64], + id[75]); + DPRINTK("80==0x%04x " + "81==0x%04x " + "82==0x%04x " + "83==0x%04x " + "84==0x%04x \n", + id[80], + id[81], + id[82], + id[83], + id[84]); + DPRINTK("88==0x%04x " + "93==0x%04x\n", + id[88], + id[93]); } -static const char * xfer_mode_str[] = { - "UDMA/16", - "UDMA/25", - "UDMA/33", - "UDMA/44", - "UDMA/66", - "UDMA/100", - "UDMA/133", - "UDMA7", - "MWDMA0", - "MWDMA1", - "MWDMA2", - "PIO0", - "PIO1", - "PIO2", - "PIO3", - "PIO4", -}; - /** - * ata_udma_string - convert UDMA bit offset to string - * @mask: mask of bits supported; only highest bit counts. + * ata_id_xfermask - Compute xfermask from the given IDENTIFY data + * @id: IDENTIFY data to compute xfer mask from * - * Determine string which represents the highest speed - * (highest bit in @udma_mask). + * Compute the xfermask for this device. This is not as trivial + * as it seems if we must consider early devices correctly. + * + * FIXME: pre IDE drive timing (do we care ?). * * LOCKING: * None. * * RETURNS: - * Constant C string representing highest speed listed in - * @udma_mask, or the constant C string "". + * Computed xfermask */ - -static const char *ata_mode_string(unsigned int mask) +static unsigned int ata_id_xfermask(const u16 *id) { - int i; + unsigned int pio_mask, mwdma_mask, udma_mask; - 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; + /* Usual case. Word 53 indicates word 64 is valid */ + if (id[ATA_ID_FIELD_VALID] & (1 << 1)) { + pio_mask = id[ATA_ID_PIO_MODES] & 0x03; + pio_mask <<= 3; + pio_mask |= 0x7; + } else { + /* If word 64 isn't valid then Word 51 high byte holds + * the PIO timing number for the maximum. Turn it into + * a mask. + */ + pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ; - return ""; + /* But wait.. there's more. Design your standards by + * committee and you too can get a free iordy field to + * process. However its the speeds not the modes that + * are supported... Note drivers using the timing API + * will get this right anyway + */ + } + + mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07; -out: - return xfer_mode_str[i]; + udma_mask = 0; + if (id[ATA_ID_FIELD_VALID] & (1 << 2)) + udma_mask = id[ATA_ID_UDMA_MODES] & 0xff; + + return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); } /** - * ata_pio_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) + * ata_port_queue_task - Queue port_task + * @ap: The ata_port to queue port_task for + * @fn: workqueue function to be scheduled + * @data: data value to pass to workqueue function + * @delay: delay time for workqueue function * - * This technique was originally described in - * Hale Landis's ATADRVR (www.ata-atapi.com), and - * later found its way into the ATA/ATAPI spec. + * Schedule @fn(@data) for execution after @delay jiffies using + * port_task. There is one port_task per port and it's the + * user(low level driver)'s responsibility to make sure that only + * one task is active at any given time. * - * Write a pattern to the ATA shadow registers, - * and if a device is present, it will respond by - * correctly storing and echoing back the - * ATA shadow register contents. + * libata core layer takes care of synchronization between + * port_task and EH. ata_port_queue_task() may be ignored for EH + * synchronization. * * LOCKING: - * caller. + * Inherited from caller. */ - -static unsigned int ata_pio_devchk(struct ata_port *ap, - unsigned int device) +void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, + unsigned long delay) { - struct ata_ioports *ioaddr = &ap->ioaddr; - u8 nsect, lbal; - - ap->ops->dev_select(ap, device); - - outb(0x55, ioaddr->nsect_addr); - outb(0xaa, ioaddr->lbal_addr); - - outb(0xaa, ioaddr->nsect_addr); - outb(0x55, ioaddr->lbal_addr); + int rc; - outb(0x55, ioaddr->nsect_addr); - outb(0xaa, ioaddr->lbal_addr); + if (ap->flags & ATA_FLAG_FLUSH_PORT_TASK) + return; - nsect = inb(ioaddr->nsect_addr); - lbal = inb(ioaddr->lbal_addr); + PREPARE_WORK(&ap->port_task, fn, data); - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ + if (!delay) + rc = queue_work(ata_wq, &ap->port_task); + else + rc = queue_delayed_work(ata_wq, &ap->port_task, delay); - return 0; /* nothing found */ + /* rc == 0 means that another user is using port task */ + WARN_ON(rc == 0); } /** - * ata_mmio_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * This technique was originally described in - * Hale Landis's ATADRVR (www.ata-atapi.com), and - * later found its way into the ATA/ATAPI spec. + * ata_port_flush_task - Flush port_task + * @ap: The ata_port to flush port_task for * - * Write a pattern to the ATA shadow registers, - * and if a device is present, it will respond by - * correctly storing and echoing back the - * ATA shadow register contents. + * After this function completes, port_task is guranteed not to + * be running or scheduled. * * LOCKING: - * caller. + * Kernel thread context (may sleep) */ - -static unsigned int ata_mmio_devchk(struct ata_port *ap, - unsigned int device) +void ata_port_flush_task(struct ata_port *ap) { - struct ata_ioports *ioaddr = &ap->ioaddr; - u8 nsect, lbal; + unsigned long flags; - ap->ops->dev_select(ap, device); + DPRINTK("ENTER\n"); - writeb(0x55, (void __iomem *) ioaddr->nsect_addr); - writeb(0xaa, (void __iomem *) ioaddr->lbal_addr); + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags |= ATA_FLAG_FLUSH_PORT_TASK; + spin_unlock_irqrestore(&ap->host_set->lock, flags); - writeb(0xaa, (void __iomem *) ioaddr->nsect_addr); - writeb(0x55, (void __iomem *) ioaddr->lbal_addr); + DPRINTK("flush #1\n"); + flush_workqueue(ata_wq); - writeb(0x55, (void __iomem *) ioaddr->nsect_addr); - writeb(0xaa, (void __iomem *) ioaddr->lbal_addr); + /* + * At this point, if a task is running, it's guaranteed to see + * the FLUSH flag; thus, it will never queue pio tasks again. + * Cancel and flush. + */ + if (!cancel_delayed_work(&ap->port_task)) { + DPRINTK("flush #2\n"); + flush_workqueue(ata_wq); + } - nsect = readb((void __iomem *) ioaddr->nsect_addr); - lbal = readb((void __iomem *) ioaddr->lbal_addr); + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_FLUSH_PORT_TASK; + spin_unlock_irqrestore(&ap->host_set->lock, flags); - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ + DPRINTK("EXIT\n"); +} - return 0; /* nothing found */ +void ata_qc_complete_internal(struct ata_queued_cmd *qc) +{ + struct completion *waiting = qc->private_data; + + qc->ap->ops->tf_read(qc->ap, &qc->tf); + complete(waiting); } /** - * ata_devchk - PATA device presence detection - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * Dispatch ATA device presence detection, depending - * on whether we are using PIO or MMIO to talk to the - * ATA shadow registers. + * ata_exec_internal - execute libata internal command + * @ap: Port to which the command is sent + * @dev: Device to which the command is sent + * @tf: Taskfile registers for the command and the result + * @dma_dir: Data tranfer direction of the command + * @buf: Data buffer of the command + * @buflen: Length of data buffer + * + * Executes libata internal command with timeout. @tf contains + * command on entry and result on return. Timeout and error + * conditions are reported via return value. No recovery action + * is taken after a command times out. It's caller's duty to + * clean up after timeout. * * LOCKING: - * caller. + * None. Should be called with kernel context, might sleep. */ -static unsigned int ata_devchk(struct ata_port *ap, - unsigned int device) +static unsigned +ata_exec_internal(struct ata_port *ap, struct ata_device *dev, + struct ata_taskfile *tf, + int dma_dir, void *buf, unsigned int buflen) { - if (ap->flags & ATA_FLAG_MMIO) - return ata_mmio_devchk(ap, device); - return ata_pio_devchk(ap, device); + u8 command = tf->command; + struct ata_queued_cmd *qc; + DECLARE_COMPLETION(wait); + unsigned long flags; + unsigned int err_mask; + + spin_lock_irqsave(&ap->host_set->lock, flags); + + qc = ata_qc_new_init(ap, dev); + BUG_ON(qc == NULL); + + qc->tf = *tf; + qc->dma_dir = dma_dir; + if (dma_dir != DMA_NONE) { + ata_sg_init_one(qc, buf, buflen); + qc->nsect = buflen / ATA_SECT_SIZE; + } + + qc->private_data = &wait; + qc->complete_fn = ata_qc_complete_internal; + + ata_qc_issue(qc); + + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) { + ata_port_flush_task(ap); + + spin_lock_irqsave(&ap->host_set->lock, flags); + + /* We're racing with irq here. If we lose, the + * following test prevents us from completing the qc + * again. If completion irq occurs after here but + * before the caller cleans up, it will result in a + * spurious interrupt. We can live with that. + */ + if (qc->flags & ATA_QCFLAG_ACTIVE) { + qc->err_mask = AC_ERR_TIMEOUT; + ata_qc_complete(qc); + printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", + ap->id, command); + } + + spin_unlock_irqrestore(&ap->host_set->lock, flags); + } + + *tf = qc->tf; + err_mask = qc->err_mask; + + ata_qc_free(qc); + + /* XXX - Some LLDDs (sata_mv) disable port on command failure. + * Until those drivers are fixed, we detect the condition + * here, fail the command with AC_ERR_SYSTEM and reenable the + * port. + * + * Note that this doesn't change any behavior as internal + * command failure results in disabling the device in the + * higher layer for LLDDs without new reset/EH callbacks. + * + * Kill the following code as soon as those drivers are fixed. + */ + if (ap->flags & ATA_FLAG_PORT_DISABLED) { + err_mask |= AC_ERR_SYSTEM; + ata_port_probe(ap); + } + + return err_mask; } /** - * ata_dev_classify - determine device type based on ATA-spec signature - * @tf: ATA taskfile register set for device to be identified - * - * Determine from taskfile register contents whether a device is - * ATA or ATAPI, as per "Signature and persistence" section - * of ATA/PI spec (volume 1, sect 5.14). + * ata_pio_need_iordy - check if iordy needed + * @adev: ATA device * - * LOCKING: - * None. - * - * RETURNS: - * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, or %ATA_DEV_UNKNOWN - * the event of failure. + * Check if the current speed of the device requires IORDY. Used + * by various controllers for chip configuration. */ -unsigned int ata_dev_classify(struct ata_taskfile *tf) +unsigned int ata_pio_need_iordy(const struct ata_device *adev) { - /* Apple's open source Darwin code hints that some devices only - * put a proper signature into the LBA mid/high registers, - * So, we only check those. It's sufficient for uniqueness. - */ + int pio; + int speed = adev->pio_mode - XFER_PIO_0; - if (((tf->lbam == 0) && (tf->lbah == 0)) || - ((tf->lbam == 0x3c) && (tf->lbah == 0xc3))) { - DPRINTK("found ATA device by sig\n"); - return ATA_DEV_ATA; - } + if (speed < 2) + return 0; + if (speed > 2) + return 1; - if (((tf->lbam == 0x14) && (tf->lbah == 0xeb)) || - ((tf->lbam == 0x69) && (tf->lbah == 0x96))) { - DPRINTK("found ATAPI device by sig\n"); - return ATA_DEV_ATAPI; - } + /* If we have no drive specific rule, then PIO 2 is non IORDY */ - DPRINTK("unknown device\n"); - return ATA_DEV_UNKNOWN; + if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */ + pio = adev->id[ATA_ID_EIDE_PIO]; + /* Is the speed faster than the drive allows non IORDY ? */ + if (pio) { + /* This is cycle times not frequency - watch the logic! */ + if (pio > 240) /* PIO2 is 240nS per cycle */ + return 1; + return 0; + } + } + return 0; } /** - * ata_dev_try_classify - Parse returned ATA device signature - * @ap: ATA channel to examine - * @device: Device to examine (starting at zero) - * - * After an event -- SRST, E.D.D., or SATA COMRESET -- occurs, - * an ATA/ATAPI-defined set of values is placed in the ATA - * shadow registers, indicating the results of device detection - * and diagnostics. - * - * Select the ATA device, and read the values from the ATA shadow - * registers. Then parse according to the Error register value, - * and the spec-defined values examined by ata_dev_classify(). + * ata_dev_read_id - Read ID data from the specified device + * @ap: port on which target device resides + * @dev: target device + * @p_class: pointer to class of the target device (may be changed) + * @post_reset: is this read ID post-reset? + * @p_id: read IDENTIFY page (newly allocated) + * + * 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 issues ATA_CMD_INIT_DEV_PARAMS + * for pre-ATA4 drives. * * LOCKING: - * caller. + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno otherwise. */ - -static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device) +static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, + unsigned int *p_class, int post_reset, u16 **p_id) { - struct ata_device *dev = &ap->device[device]; + unsigned int class = *p_class; struct ata_taskfile tf; - unsigned int class; - u8 err; + unsigned int err_mask = 0; + u16 *id; + const char *reason; + int rc; - ap->ops->dev_select(ap, device); + DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); - memset(&tf, 0, sizeof(tf)); + ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ - err = ata_chk_err(ap); - ap->ops->tf_read(ap, &tf); + id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); + if (id == NULL) { + rc = -ENOMEM; + reason = "out of memory"; + goto err_out; + } - dev->class = ATA_DEV_NONE; + retry: + ata_tf_init(ap, &tf, dev->devno); - /* see if device passed diags */ - if (err == 1) - /* do nothing */ ; - else if ((device == 0) && (err == 0x81)) - /* do nothing */ ; - else - return err; + switch (class) { + case ATA_DEV_ATA: + tf.command = ATA_CMD_ID_ATA; + break; + case ATA_DEV_ATAPI: + tf.command = ATA_CMD_ID_ATAPI; + break; + default: + rc = -ENODEV; + reason = "unsupported class"; + goto err_out; + } - /* determine if device if ATA or ATAPI */ - class = ata_dev_classify(&tf); - if (class == ATA_DEV_UNKNOWN) - return err; - if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0)) - return err; + tf.protocol = ATA_PROT_PIO; - dev->class = class; + 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"; + goto err_out; + } - return err; -} + swap_buf_le16(id, ATA_ID_WORDS); -/** - * ata_dev_id_string - Convert IDENTIFY DEVICE page into string - * @id: IDENTIFY DEVICE results we will examine - * @s: string into which data is output - * @ofs: offset into identify device page - * @len: length of string to return. must be an even number. - * - * The strings in the IDENTIFY DEVICE page are broken up into - * 16-bit chunks. Run through the string, and output each - * 8-bit chunk linearly, regardless of platform. - * - * LOCKING: - * caller. - */ + /* sanity check */ + 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; + } -void ata_dev_id_string(u16 *id, unsigned char *s, - unsigned int ofs, unsigned int len) -{ - unsigned int c; + if (post_reset && class == ATA_DEV_ATA) { + /* + * The exact sequence expected by certain pre-ATA4 drives is: + * SRST RESET + * IDENTIFY + * INITIALIZE DEVICE PARAMETERS + * anything else.. + * 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, id[3], id[6]); + if (err_mask) { + rc = -EIO; + reason = "INIT_DEV_PARAMS failed"; + goto err_out; + } - while (len > 0) { - c = id[ofs] >> 8; - *s = c; - s++; + /* current CHS translation info (id[53-58]) might be + * changed. reread the identify device info. + */ + post_reset = 0; + goto retry; + } + } - c = id[ofs] & 0xff; - *s = c; - s++; + *p_class = class; + *p_id = id; + return 0; - ofs++; - len -= 2; - } + err_out: + printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n", + ap->id, dev->devno, reason); + kfree(id); + return rc; } - -/** - * ata_noop_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * This function performs no actual function. - * - * May be used as the dev_select() entry in ata_port_operations. - * - * LOCKING: - * caller. - */ -void ata_noop_dev_select (struct ata_port *ap, unsigned int device) +static inline u8 ata_dev_knobble(const struct ata_port *ap, + struct ata_device *dev) { + return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); } - /** - * ata_std_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * Use the method defined in the ATA specification to - * make either device 0, or device 1, active on the - * ATA channel. Works with both PIO and MMIO. + * ata_dev_configure - Configure the specified ATA/ATAPI device + * @ap: Port on which target device resides + * @dev: Target device to configure + * @print_info: Enable device info printout * - * May be used as the dev_select() entry in ata_port_operations. + * Configure @dev according to @dev->id. Generic and low-level + * driver specific fixups are also applied. * * LOCKING: - * caller. + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -errno otherwise */ - -void ata_std_dev_select (struct ata_port *ap, unsigned int device) -{ - u8 tmp; - - if (device == 0) - tmp = ATA_DEVICE_OBS; - else - tmp = ATA_DEVICE_OBS | ATA_DEV1; - - if (ap->flags & ATA_FLAG_MMIO) { - writeb(tmp, (void __iomem *) ap->ioaddr.device_addr); - } else { - outb(tmp, ap->ioaddr.device_addr); - } - ata_pause(ap); /* needed; also flushes, for mmio */ -} - -/** - * ata_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * @wait: non-zero to wait for Status register BSY bit to clear - * @can_sleep: non-zero if context allows sleeping - * - * Use the method defined in the ATA specification to - * make either device 0, or device 1, active on the - * ATA channel. - * - * This is a high-level version of ata_std_dev_select(), - * which additionally provides the services of inserting - * the proper pauses and status polling, where needed. - * - * LOCKING: - * caller. - */ - -void ata_dev_select(struct ata_port *ap, unsigned int device, - unsigned int wait, unsigned int can_sleep) -{ - VPRINTK("ENTER, ata%u: device %u, wait %u\n", - ap->id, device, wait); - - if (wait) - ata_wait_idle(ap); - - ap->ops->dev_select(ap, device); - - if (wait) { - if (can_sleep && ap->device[device].class == ATA_DEV_ATAPI) - msleep(150); - ata_wait_idle(ap); - } -} - -/** - * ata_dump_id - IDENTIFY DEVICE info debugging output - * @dev: Device whose IDENTIFY DEVICE page we will dump - * - * Dump selected 16-bit words from a detected device's - * IDENTIFY PAGE page. - * - * LOCKING: - * caller. - */ - -static inline void ata_dump_id(struct ata_device *dev) -{ - DPRINTK("49==0x%04x " - "53==0x%04x " - "63==0x%04x " - "64==0x%04x " - "75==0x%04x \n", - dev->id[49], - dev->id[53], - dev->id[63], - dev->id[64], - dev->id[75]); - DPRINTK("80==0x%04x " - "81==0x%04x " - "82==0x%04x " - "83==0x%04x " - "84==0x%04x \n", - dev->id[80], - dev->id[81], - dev->id[82], - dev->id[83], - dev->id[84]); - DPRINTK("88==0x%04x " - "93==0x%04x\n", - dev->id[88], - dev->id[93]); -} - -/** - * ata_dev_identify - obtain IDENTIFY x DEVICE page - * @ap: port on which device we wish to probe resides - * @device: device bus address, starting at zero - * - * Following bus reset, we issue the IDENTIFY [PACKET] DEVICE - * command, and read back the 512-byte device information page. - * The device information page is fed to us via the standard - * PIO-IN protocol, but we hand-code it here. (TODO: investigate - * using standard PIO-IN paths) - * - * After reading the device information page, we use several - * bits of information from it to initialize data structures - * that will be used during the lifetime of the ata_device. - * Other data from the info page is used to disqualify certain - * older ATA devices we do not wish to support. - * - * LOCKING: - * Inherited from caller. Some functions called by this function - * obtain the host_set lock. - */ - -static void ata_dev_identify(struct ata_port *ap, unsigned int device) -{ - struct ata_device *dev = &ap->device[device]; - unsigned int i; - u16 tmp; - unsigned long xfer_modes; - u8 status; - unsigned int using_edd; - DECLARE_COMPLETION(wait); - struct ata_queued_cmd *qc; - unsigned long flags; - int rc; +static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev, + int print_info) +{ + const u16 *id = dev->id; + unsigned int xfer_mask; + int i, rc; if (!ata_dev_present(dev)) { DPRINTK("ENTER/EXIT (host %u, dev %u) -- nodev\n", - ap->id, device); - return; - } - - if (ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) - using_edd = 0; - else - using_edd = 1; - - DPRINTK("ENTER, host %u, dev %u\n", ap->id, device); - - assert (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ATAPI || - dev->class == ATA_DEV_NONE); - - ata_dev_select(ap, device, 1, 1); /* select device 0/1 */ - - qc = ata_qc_new_init(ap, dev); - BUG_ON(qc == NULL); - - ata_sg_init_one(qc, dev->id, sizeof(dev->id)); - qc->dma_dir = DMA_FROM_DEVICE; - qc->tf.protocol = ATA_PROT_PIO; - qc->nsect = 1; - -retry: - if (dev->class == ATA_DEV_ATA) { - qc->tf.command = ATA_CMD_ID_ATA; - DPRINTK("do ATA identify\n"); - } else { - qc->tf.command = ATA_CMD_ID_ATAPI; - DPRINTK("do ATAPI identify\n"); - } - - qc->waiting = &wait; - qc->complete_fn = ata_qc_complete_noop; - - spin_lock_irqsave(&ap->host_set->lock, flags); - rc = ata_qc_issue(qc); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - if (rc) - goto err_out; - else - wait_for_completion(&wait); - - status = ata_chk_status(ap); - if (status & ATA_ERR) { - /* - * 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) && (qc->tf.command == ATA_CMD_ID_ATA)) { - u8 err = ata_chk_err(ap); - if (err & ATA_ABORTED) { - dev->class = ATA_DEV_ATAPI; - qc->cursg = 0; - qc->cursg_ofs = 0; - qc->cursect = 0; - qc->nsect = 1; - goto retry; - } - } - goto err_out; + ap->id, dev->devno); + return 0; } - swap_buf_le16(dev->id, ATA_ID_WORDS); + DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); /* print device capabilities */ - printk(KERN_DEBUG "ata%u: dev %u cfg " - "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", - ap->id, device, dev->id[49], - dev->id[82], dev->id[83], dev->id[84], - dev->id[85], dev->id[86], dev->id[87], - dev->id[88]); + if (print_info) + printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x " + "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", + ap->id, dev->devno, id[49], id[82], id[83], + id[84], id[85], id[86], id[87], id[88]); + + /* initialize to-be-configured parameters */ + dev->flags = 0; + dev->max_sectors = 0; + dev->cdb_len = 0; + dev->n_sectors = 0; + dev->cylinders = 0; + dev->heads = 0; + dev->sectors = 0; /* * common ATA, ATAPI feature tests */ - /* we require LBA and DMA support (bits 8 & 9 of word 49) */ - if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { - printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); - goto err_out_nosup; - } - - /* quick-n-dirty find max transfer mode; for printk only */ - 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); - } + /* find max transfer mode; for printk only */ + xfer_mask = ata_id_xfermask(id); - ata_dump_id(dev); + ata_dump_id(id); /* ATA-specific feature tests */ if (dev->class == ATA_DEV_ATA) { - if (!ata_id_is_ata(dev->id)) /* sanity check */ - goto err_out_nosup; + dev->n_sectors = ata_id_n_sectors(id); - tmp = dev->id[ATA_ID_MAJOR_VER]; - for (i = 14; i >= 1; i--) - if (tmp & (1 << i)) - break; + if (ata_id_has_lba(id)) { + const char *lba_desc; - /* we require at least ATA-3 */ - if (i < 3) { - printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); - goto err_out_nosup; - } + lba_desc = "LBA"; + dev->flags |= ATA_DFLAG_LBA; + if (ata_id_has_lba48(id)) { + dev->flags |= ATA_DFLAG_LBA48; + lba_desc = "LBA48"; + } - if (ata_id_has_lba48(dev->id)) { - dev->flags |= ATA_DFLAG_LBA48; - dev->n_sectors = ata_id_u64(dev->id, 100); + /* print device info to dmesg */ + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATA-%d, " + "max %s, %Lu sectors: %s\n", + ap->id, dev->devno, + ata_id_major_version(id), + ata_mode_string(xfer_mask), + (unsigned long long)dev->n_sectors, + lba_desc); } else { - dev->n_sectors = ata_id_u32(dev->id, 60); - } + /* CHS */ + + /* Default translation */ + dev->cylinders = id[1]; + dev->heads = id[3]; + dev->sectors = id[6]; + + if (ata_id_current_chs_valid(id)) { + /* Current CHS translation is valid. */ + dev->cylinders = id[54]; + dev->heads = id[55]; + dev->sectors = id[56]; + } - ap->host->max_cmd_len = 16; + /* print device info to dmesg */ + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATA-%d, " + "max %s, %Lu sectors: CHS %u/%u/%u\n", + ap->id, dev->devno, + ata_id_major_version(id), + ata_mode_string(xfer_mask), + (unsigned long long)dev->n_sectors, + dev->cylinders, dev->heads, dev->sectors); + } - /* print device info to dmesg */ - printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", - ap->id, device, - ata_mode_string(xfer_modes), - (unsigned long long)dev->n_sectors, - dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); + dev->cdb_len = 16; } /* ATAPI-specific feature tests */ - else { - if (ata_id_is_ata(dev->id)) /* sanity check */ - goto err_out_nosup; - - rc = atapi_cdb_len(dev->id); + else if (dev->class == ATA_DEV_ATAPI) { + rc = atapi_cdb_len(id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id); + rc = -EINVAL; goto err_out_nosup; } - ap->cdb_len = (unsigned int) rc; - ap->host->max_cmd_len = (unsigned char) ap->cdb_len; + dev->cdb_len = (unsigned int) rc; /* print device info to dmesg */ - printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", - ap->id, device, - ata_mode_string(xfer_modes)); + if (print_info) + printk(KERN_INFO "ata%u: dev %u ATAPI, max %s\n", + ap->id, dev->devno, ata_mode_string(xfer_mask)); } - DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap)); - return; - -err_out_nosup: - printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n", - ap->id, device); -err_out: - dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */ - DPRINTK("EXIT, err\n"); -} - - -static inline u8 ata_dev_knobble(struct ata_port *ap) -{ - return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id))); -} - -/** - * ata_dev_config - Run device specific handlers and check for - * SATA->PATA bridges - * @ap: Bus - * @i: Device - * - * LOCKING: - */ + ap->host->max_cmd_len = 0; + for (i = 0; i < ATA_MAX_DEVICES; i++) + ap->host->max_cmd_len = max_t(unsigned int, + ap->host->max_cmd_len, + ap->device[i].cdb_len); -void ata_dev_config(struct ata_port *ap, unsigned int i) -{ /* limit bridge transfers to udma5, 200 sectors */ - if (ata_dev_knobble(ap)) { - printk(KERN_INFO "ata%u(%u): applying bridge limits\n", - ap->id, ap->device->devno); - ap->udma_mask &= ATA_UDMA5; - ap->host->max_sectors = ATA_MAX_SECTORS; - ap->host->hostt->max_sectors = ATA_MAX_SECTORS; - ap->device->flags |= ATA_DFLAG_LOCK_SECTORS; + if (ata_dev_knobble(ap, dev)) { + if (print_info) + printk(KERN_INFO "ata%u(%u): applying bridge limits\n", + ap->id, dev->devno); + dev->udma_mask &= ATA_UDMA5; + dev->max_sectors = ATA_MAX_SECTORS; } if (ap->ops->dev_config) - ap->ops->dev_config(ap, &ap->device[i]); + ap->ops->dev_config(ap, dev); + + DPRINTK("EXIT, drv_stat = 0x%x\n", ata_chk_status(ap)); + return 0; + +err_out_nosup: + DPRINTK("EXIT, err\n"); + return rc; } /** @@ -1357,24 +1357,66 @@ void ata_dev_config(struct ata_port *ap, unsigned int i) static int ata_bus_probe(struct ata_port *ap) { - unsigned int i, found = 0; + unsigned int classes[ATA_MAX_DEVICES]; + unsigned int i, rc, found = 0; - ap->ops->phy_reset(ap); - if (ap->flags & ATA_FLAG_PORT_DISABLED) - goto err_out; + ata_port_probe(ap); + + /* reset and determine device classes */ + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_UNKNOWN; + + if (ap->ops->probe_reset) { + rc = ap->ops->probe_reset(ap, classes); + if (rc) { + printk("ata%u: reset failed (errno=%d)\n", ap->id, rc); + return rc; + } + } else { + ap->ops->phy_reset(ap); + + if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ap->device[i].class; + ata_port_probe(ap); + } + + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] == ATA_DEV_UNKNOWN) + classes[i] = ATA_DEV_NONE; + + /* read IDENTIFY page and configure devices */ for (i = 0; i < ATA_MAX_DEVICES; i++) { - ata_dev_identify(ap, i); - if (ata_dev_present(&ap->device[i])) { - found = 1; - ata_dev_config(ap,i); + struct ata_device *dev = &ap->device[i]; + + dev->class = classes[i]; + + if (!ata_dev_present(dev)) + continue; + + WARN_ON(dev->id != NULL); + if (ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id)) { + dev->class = ATA_DEV_NONE; + continue; + } + + if (ata_dev_configure(ap, dev, 1)) { + ata_dev_disable(ap, dev); + continue; } + + found = 1; } - if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED)) + 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; @@ -1382,7 +1424,6 @@ static int ata_bus_probe(struct ata_port *ap) err_out_disable: ap->ops->port_disable(ap); -err_out: return -1; } @@ -1403,6 +1444,41 @@ void ata_port_probe(struct ata_port *ap) } /** + * sata_print_link_status - Print SATA link status + * @ap: SATA port to printk link status about + * + * This function prints link speed and status of a SATA link. + * + * LOCKING: + * None. + */ +static void sata_print_link_status(struct ata_port *ap) +{ + u32 sstatus, tmp; + const char *speed; + + if (!ap->ops->scr_read) + return; + + sstatus = scr_read(ap, SCR_STATUS); + + if (sata_dev_present(ap)) { + tmp = (sstatus >> 4) & 0xf; + if (tmp & (1 << 0)) + speed = "1.5"; + else if (tmp & (1 << 1)) + speed = "3.0"; + else + speed = ""; + printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n", + ap->id, speed, sstatus); + } else { + printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n", + ap->id, sstatus); + } +} + +/** * __sata_phy_reset - Wake/reset a low-level SATA PHY * @ap: SATA port associated with target SATA PHY. * @@ -1436,15 +1512,14 @@ void __sata_phy_reset(struct ata_port *ap) break; } while (time_before(jiffies, timeout)); + /* print link status */ + sata_print_link_status(ap); + /* TODO: phy layer with polling, timeouts, etc. */ if (sata_dev_present(ap)) ata_port_probe(ap); - else { - sstatus = scr_read(ap, SCR_STATUS); - printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n", - ap->id, sstatus); + else ata_port_disable(ap); - } if (ap->flags & ATA_FLAG_PORT_DISABLED) return; @@ -1477,6 +1552,23 @@ void sata_phy_reset(struct ata_port *ap) } /** + * ata_dev_pair - return other device on cable + * @ap: port + * @adev: device + * + * Obtain the other device on the same cable, or if none is + * present NULL is returned + */ + +struct ata_device *ata_dev_pair(struct ata_port *ap, struct ata_device *adev) +{ + struct ata_device *pair = &ap->device[1 - adev->devno]; + if (!ata_dev_present(pair)) + return NULL; + return pair; +} + +/** * ata_port_disable - Disable port. * @ap: Port to be disabled. * @@ -1496,605 +1588,1117 @@ void ata_port_disable(struct ata_port *ap) ap->flags |= ATA_FLAG_PORT_DISABLED; } -static struct { - unsigned int shift; - u8 base; -} xfer_mode_classes[] = { - { ATA_SHIFT_UDMA, XFER_UDMA_0 }, - { ATA_SHIFT_MWDMA, XFER_MW_DMA_0 }, - { ATA_SHIFT_PIO, XFER_PIO_0 }, +/* + * This mode timing computation functionality is ported over from + * drivers/ide/ide-timing.h and was originally written by Vojtech Pavlik + */ +/* + * PIO 0-5, MWDMA 0-2 and UDMA 0-6 timings (in nanoseconds). + * These were taken from ATA/ATAPI-6 standard, rev 0a, except + * for PIO 5, which is a nonstandard extension and UDMA6, which + * is currently supported only by Maxtor drives. + */ + +static const struct ata_timing ata_timing[] = { + + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 }, + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 }, + { XFER_UDMA_4, 0, 0, 0, 0, 0, 0, 0, 30 }, + { XFER_UDMA_3, 0, 0, 0, 0, 0, 0, 0, 45 }, + + { XFER_UDMA_2, 0, 0, 0, 0, 0, 0, 0, 60 }, + { XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 }, + { XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 }, + +/* { XFER_UDMA_SLOW, 0, 0, 0, 0, 0, 0, 0, 150 }, */ + + { XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 }, + { XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 }, + { XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 }, + + { XFER_SW_DMA_2, 60, 0, 0, 0, 120, 120, 240, 0 }, + { XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 }, + { XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 }, + +/* { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 }, */ + { XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 }, + { XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 }, + + { XFER_PIO_2, 30, 290, 40, 330, 100, 90, 240, 0 }, + { XFER_PIO_1, 50, 290, 93, 383, 125, 100, 383, 0 }, + { XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0 }, + +/* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ + + { 0xFF } }; -static inline u8 base_from_shift(unsigned int shift) +#define ENOUGH(v,unit) (((v)-1)/(unit)+1) +#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) + +static void ata_timing_quantize(const struct ata_timing *t, struct ata_timing *q, int T, int UT) { - int i; + q->setup = EZ(t->setup * 1000, T); + q->act8b = EZ(t->act8b * 1000, T); + q->rec8b = EZ(t->rec8b * 1000, T); + q->cyc8b = EZ(t->cyc8b * 1000, T); + q->active = EZ(t->active * 1000, T); + q->recover = EZ(t->recover * 1000, T); + q->cycle = EZ(t->cycle * 1000, T); + q->udma = EZ(t->udma * 1000, UT); +} + +void ata_timing_merge(const struct ata_timing *a, const struct ata_timing *b, + struct ata_timing *m, unsigned int what) +{ + if (what & ATA_TIMING_SETUP ) m->setup = max(a->setup, b->setup); + if (what & ATA_TIMING_ACT8B ) m->act8b = max(a->act8b, b->act8b); + if (what & ATA_TIMING_REC8B ) m->rec8b = max(a->rec8b, b->rec8b); + if (what & ATA_TIMING_CYC8B ) m->cyc8b = max(a->cyc8b, b->cyc8b); + if (what & ATA_TIMING_ACTIVE ) m->active = max(a->active, b->active); + if (what & ATA_TIMING_RECOVER) m->recover = max(a->recover, b->recover); + if (what & ATA_TIMING_CYCLE ) m->cycle = max(a->cycle, b->cycle); + if (what & ATA_TIMING_UDMA ) m->udma = max(a->udma, b->udma); +} + +static const struct ata_timing* ata_timing_find_mode(unsigned short speed) +{ + const struct ata_timing *t; + + for (t = ata_timing; t->mode != speed; t++) + if (t->mode == 0xFF) + return NULL; + return t; +} + +int ata_timing_compute(struct ata_device *adev, unsigned short speed, + struct ata_timing *t, int T, int UT) +{ + const struct ata_timing *s; + struct ata_timing p; + + /* + * Find the mode. + */ + + if (!(s = ata_timing_find_mode(speed))) + return -EINVAL; + + memcpy(t, s, sizeof(*s)); + + /* + * If the drive is an EIDE drive, it can tell us it needs extended + * PIO/MW_DMA cycle timing. + */ + + if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */ + memset(&p, 0, sizeof(p)); + if(speed >= XFER_PIO_0 && speed <= XFER_SW_DMA_0) { + if (speed <= XFER_PIO_2) p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO]; + else p.cycle = p.cyc8b = adev->id[ATA_ID_EIDE_PIO_IORDY]; + } else if(speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) { + p.cycle = adev->id[ATA_ID_EIDE_DMA_MIN]; + } + ata_timing_merge(&p, t, t, ATA_TIMING_CYCLE | ATA_TIMING_CYC8B); + } + + /* + * Convert the timing to bus clock counts. + */ - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) - if (xfer_mode_classes[i].shift == shift) - return xfer_mode_classes[i].base; + ata_timing_quantize(t, t, T, UT); + + /* + * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, + * S.M.A.R.T * and some other commands. We have to ensure that the + * DMA cycle timing is slower/equal than the fastest PIO timing. + */ + + if (speed > XFER_PIO_4) { + ata_timing_compute(adev, adev->pio_mode, &p, T, UT); + ata_timing_merge(&p, t, t, ATA_TIMING_ALL); + } + + /* + * Lengthen active & recovery time so that cycle time is correct. + */ + + if (t->act8b + t->rec8b < t->cyc8b) { + t->act8b += (t->cyc8b - (t->act8b + t->rec8b)) / 2; + t->rec8b = t->cyc8b - t->act8b; + } + + if (t->active + t->recover < t->cycle) { + t->active += (t->cycle - (t->active + t->recover)) / 2; + t->recover = t->cycle - t->active; + } + + return 0; +} + +static int ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) +{ + unsigned int err_mask; + int rc; + + if (dev->xfer_shift == ATA_SHIFT_PIO) + dev->flags |= ATA_DFLAG_PIO; + + err_mask = ata_dev_set_xfermode(ap, dev); + if (err_mask) { + printk(KERN_ERR + "ata%u: failed to set xfermode (err_mask=0x%x)\n", + ap->id, err_mask); + return -EIO; + } + + rc = ata_dev_revalidate(ap, dev, 0); + if (rc) { + printk(KERN_ERR + "ata%u: failed to revalidate after set xfermode\n", + ap->id); + return rc; + } + + DPRINTK("xfer_shift=%u, xfer_mode=0x%x\n", + dev->xfer_shift, (int)dev->xfer_mode); + + printk(KERN_INFO "ata%u: dev %u configured for %s\n", + ap->id, dev->devno, + ata_mode_string(ata_xfer_mode2mask(dev->xfer_mode))); + return 0; +} + +static int ata_host_set_pio(struct ata_port *ap) +{ + int i; + + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + + if (!ata_dev_present(dev)) + continue; + + if (!dev->pio_mode) { + printk(KERN_WARNING "ata%u: no PIO support for device %d.\n", ap->id, i); + return -1; + } + + dev->xfer_mode = dev->pio_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) +{ + 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) + continue; + + dev->xfer_mode = dev->dma_mode; + dev->xfer_shift = ata_xfer_mode2shift(dev->dma_mode); + 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 + * + * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). + * + * LOCKING: + * PCI/etc. bus probe sem. + */ +static void ata_set_mode(struct ata_port *ap) +{ + int i, rc, used_dma = 0; + + /* step 1: calculate xfer_mask */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + unsigned int pio_mask, dma_mask; + + if (!ata_dev_present(dev)) + continue; + + ata_dev_xfermask(ap, dev); + + /* TODO: let LLDD filter dev->*_mask here */ + + pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0); + 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 */ + rc = ata_host_set_pio(ap); + if (rc) + goto err_out; + + /* step 3: set host DMA timings */ + ata_host_set_dma(ap); + + /* step 4: update devices' xfer mode */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + + if (!ata_dev_present(dev)) + continue; + + if (ata_dev_set_mode(ap, dev)) + 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); + + return; + +err_out: + ata_port_disable(ap); +} + +/** + * ata_tf_to_host - issue ATA taskfile to host controller + * @ap: port to which command is being issued + * @tf: ATA taskfile register set + * + * Issues ATA taskfile register set to ATA host controller, + * with proper synchronization with interrupt handler and + * other threads. + * + * LOCKING: + * spin_lock_irqsave(host_set lock) + */ + +static inline void ata_tf_to_host(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + ap->ops->tf_load(ap, tf); + ap->ops->exec_command(ap, tf); +} + +/** + * ata_busy_sleep - sleep until BSY clears, or timeout + * @ap: port containing status register to be polled + * @tmout_pat: impatience timeout + * @tmout: overall timeout + * + * Sleep until ATA Status register bit BSY clears, + * or a timeout occurs. + * + * LOCKING: None. + */ + +unsigned int ata_busy_sleep (struct ata_port *ap, + unsigned long tmout_pat, unsigned long tmout) +{ + unsigned long timer_start, timeout; + u8 status; + + status = ata_busy_wait(ap, ATA_BUSY, 300); + timer_start = jiffies; + timeout = timer_start + tmout_pat; + while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { + msleep(50); + status = ata_busy_wait(ap, ATA_BUSY, 3); + } + + if (status & ATA_BUSY) + printk(KERN_WARNING "ata%u is slow to respond, " + "please be patient\n", ap->id); + + timeout = timer_start + tmout; + while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { + msleep(50); + status = ata_chk_status(ap); + } + + if (status & ATA_BUSY) { + printk(KERN_ERR "ata%u failed to respond (%lu secs)\n", + ap->id, tmout / HZ); + return 1; + } + + return 0; +} + +static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + unsigned int dev0 = devmask & (1 << 0); + unsigned int dev1 = devmask & (1 << 1); + unsigned long timeout; + + /* if device 0 was found in ata_devchk, wait for its + * BSY bit to clear + */ + if (dev0) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + + /* if device 1 was found in ata_devchk, wait for + * register access, then wait for BSY to clear + */ + timeout = jiffies + ATA_TMOUT_BOOT; + while (dev1) { + u8 nsect, lbal; + + ap->ops->dev_select(ap, 1); + if (ap->flags & ATA_FLAG_MMIO) { + nsect = readb((void __iomem *) ioaddr->nsect_addr); + lbal = readb((void __iomem *) ioaddr->lbal_addr); + } else { + nsect = inb(ioaddr->nsect_addr); + lbal = inb(ioaddr->lbal_addr); + } + if ((nsect == 1) && (lbal == 1)) + break; + if (time_after(jiffies, timeout)) { + dev1 = 0; + break; + } + msleep(50); /* give drive a breather */ + } + if (dev1) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + + /* is all this really necessary? */ + ap->ops->dev_select(ap, 0); + if (dev1) + ap->ops->dev_select(ap, 1); + if (dev0) + ap->ops->dev_select(ap, 0); +} + +static unsigned int ata_bus_softreset(struct ata_port *ap, + unsigned int devmask) +{ + struct ata_ioports *ioaddr = &ap->ioaddr; + + DPRINTK("ata%u: bus reset via SRST\n", ap->id); + + /* software reset. causes dev0 to be selected */ + if (ap->flags & ATA_FLAG_MMIO) { + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + udelay(20); /* FIXME: flush */ + writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr); + udelay(20); /* FIXME: flush */ + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + } else { + outb(ap->ctl, ioaddr->ctl_addr); + udelay(10); + outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr); + udelay(10); + outb(ap->ctl, ioaddr->ctl_addr); + } + + /* spec mandates ">= 2ms" before checking status. + * We wait 150ms, because that was the magic delay used for + * ATAPI devices in Hale Landis's ATADRVR, for the period of time + * between when the ATA command register is written, and then + * status is checked. Because waiting for "a while" before + * checking status is fine, post SRST, we perform this magic + * delay here as well. + * + * Old drivers/ide uses the 2mS rule and then waits for ready + */ + 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. + */ + if (ata_check_status(ap) == 0xFF) + return AC_ERR_OTHER; + + ata_bus_post_reset(ap, devmask); + + return 0; +} + +/** + * ata_bus_reset - reset host port and associated ATA channel + * @ap: port to reset + * + * This is typically the first time we actually start issuing + * commands to the ATA channel. We wait for BSY to clear, then + * issue EXECUTE DEVICE DIAGNOSTIC command, polling for its + * result. Determine what devices, if any, are on the channel + * by looking at the device 0/1 error register. Look at the signature + * stored in each device's taskfile registers, to determine if + * the device is ATA or ATAPI. + * + * LOCKING: + * PCI/etc. bus probe sem. + * Obtains host_set lock. + * + * SIDE EFFECTS: + * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. + */ + +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, devmask = 0; + + DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); + + /* determine if device 0/1 are present */ + if (ap->flags & ATA_FLAG_SATA_RESET) + dev0 = 1; + else { + dev0 = ata_devchk(ap, 0); + if (slave_possible) + dev1 = ata_devchk(ap, 1); + } + + if (dev0) + devmask |= (1 << 0); + if (dev1) + devmask |= (1 << 1); + + /* select device 0 again */ + ap->ops->dev_select(ap, 0); + + /* issue bus reset */ + if (ap->flags & ATA_FLAG_SRST) + if (ata_bus_softreset(ap, devmask)) + goto err_out; - return 0xff; -} + /* + * determine by signature whether we have ATA or ATAPI devices + */ + ap->device[0].class = ata_dev_try_classify(ap, 0, &err); + if ((slave_possible) && (err != 0x81)) + ap->device[1].class = ata_dev_try_classify(ap, 1, &err); -static void ata_dev_set_mode(struct ata_port *ap, struct ata_device *dev) -{ - int ofs, idx; - u8 base; + /* re-enable interrupts */ + if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ + ata_irq_on(ap); - if (!ata_dev_present(dev) || (ap->flags & ATA_FLAG_PORT_DISABLED)) - return; + /* is double-select really necessary? */ + if (ap->device[1].class != ATA_DEV_NONE) + ap->ops->dev_select(ap, 1); + if (ap->device[0].class != ATA_DEV_NONE) + ap->ops->dev_select(ap, 0); - if (dev->xfer_shift == ATA_SHIFT_PIO) - dev->flags |= ATA_DFLAG_PIO; + /* if no devices were detected, disable this port */ + if ((ap->device[0].class == ATA_DEV_NONE) && + (ap->device[1].class == ATA_DEV_NONE)) + goto err_out; - ata_dev_set_xfermode(ap, dev); + if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { + /* set up device control for ATA_FLAG_SATA_RESET */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); + } - base = base_from_shift(dev->xfer_shift); - ofs = dev->xfer_mode - base; - idx = ofs + dev->xfer_shift; - WARN_ON(idx >= ARRAY_SIZE(xfer_mode_str)); + DPRINTK("EXIT\n"); + return; - DPRINTK("idx=%d xfer_shift=%u, xfer_mode=0x%x, base=0x%x, offset=%d\n", - idx, dev->xfer_shift, (int)dev->xfer_mode, (int)base, ofs); +err_out: + printk(KERN_ERR "ata%u: disabling port\n", ap->id); + ap->ops->port_disable(ap); - printk(KERN_INFO "ata%u: dev %u configured for %s\n", - ap->id, dev->devno, xfer_mode_str[idx]); + DPRINTK("EXIT\n"); } -static int ata_host_set_pio(struct ata_port *ap) +static int sata_phy_resume(struct ata_port *ap) { - unsigned int mask; - int x, i; - u8 base, xfer_mode; - - 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; + unsigned long timeout = jiffies + (HZ * 5); + u32 sstatus; - DPRINTK("base 0x%x xfer_mode 0x%x mask 0x%x x %d\n", - (int)base, (int)xfer_mode, mask, x); + scr_write_flush(ap, SCR_CONTROL, 0x300); - 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); - } - } + /* Wait for phy to become ready, if necessary. */ + do { + msleep(200); + sstatus = scr_read(ap, SCR_STATUS); + if ((sstatus & 0xf) != 1) + return 0; + } while (time_before(jiffies, timeout)); - return 0; + return -1; } -static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, - unsigned int xfer_shift) +/** + * ata_std_probeinit - initialize probing + * @ap: port to be probed + * + * @ap is about to be probed. Initialize it. This function is + * to be used as standard callback for ata_drive_probe_reset(). + * + * NOTE!!! Do not use this function as probeinit if a low level + * driver implements only hardreset. Just pass NULL as probeinit + * in that case. Using this function is probably okay but doing + * so makes reset sequence different from the original + * ->phy_reset implementation and Jeff nervous. :-P + */ +void ata_std_probeinit(struct ata_port *ap) { - 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); - } + 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); } } /** - * ata_set_mode - Program timings and issue SET FEATURES - XFER - * @ap: port on which timings will be programmed + * ata_std_softreset - reset host port via ATA SRST + * @ap: port to reset + * @verbose: fail verbosely + * @classes: resulting classes of attached devices * - * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). + * Reset host port using ATA SRST. This function is to be used + * as standard callback for ata_drive_*_reset() functions. * * LOCKING: - * PCI/etc. bus probe sem. + * Kernel thread context (may sleep) * + * RETURNS: + * 0 on success, -errno otherwise. */ -static void ata_set_mode(struct ata_port *ap) +int ata_std_softreset(struct ata_port *ap, int verbose, unsigned int *classes) { - unsigned int i, xfer_shift; - u8 xfer_mode; - int rc; - - /* step 1: always set host PIO timings */ - rc = ata_host_set_pio(ap); - if (rc) - goto err_out; - - /* 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; + unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; + unsigned int devmask = 0, err_mask; + u8 err; - /* 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); + DPRINTK("ENTER\n"); - /* step 4: update devices' xfer mode */ - ata_dev_set_mode(ap, &ap->device[0]); - ata_dev_set_mode(ap, &ap->device[1]); + if (ap->ops->scr_read && !sata_dev_present(ap)) { + classes[0] = ATA_DEV_NONE; + goto out; + } - if (ap->flags & ATA_FLAG_PORT_DISABLED) - return; + /* determine if device 0/1 are present */ + if (ata_devchk(ap, 0)) + devmask |= (1 << 0); + if (slave_possible && ata_devchk(ap, 1)) + devmask |= (1 << 1); - if (ap->ops->post_set_mode) - ap->ops->post_set_mode(ap); + /* select device 0 again */ + ap->ops->dev_select(ap, 0); - for (i = 0; i < 2; i++) { - struct ata_device *dev = &ap->device[i]; - ata_dev_set_protocol(dev); + /* issue bus reset */ + DPRINTK("about to softreset, devmask=%x\n", devmask); + err_mask = ata_bus_softreset(ap, devmask); + if (err_mask) { + if (verbose) + printk(KERN_ERR "ata%u: SRST failed (err_mask=0x%x)\n", + ap->id, err_mask); + else + DPRINTK("EXIT, softreset failed (err_mask=0x%x)\n", + err_mask); + return -EIO; } - return; + /* determine by signature whether we have ATA or ATAPI devices */ + classes[0] = ata_dev_try_classify(ap, 0, &err); + if (slave_possible && err != 0x81) + classes[1] = ata_dev_try_classify(ap, 1, &err); -err_out: - ata_port_disable(ap); + out: + DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); + return 0; } /** - * ata_busy_sleep - sleep until BSY clears, or timeout - * @ap: port containing status register to be polled - * @tmout_pat: impatience timeout - * @tmout: overall timeout + * sata_std_hardreset - reset host port via SATA phy reset + * @ap: port to reset + * @verbose: fail verbosely + * @class: resulting class of attached device * - * Sleep until ATA Status register bit BSY clears, - * or a timeout occurs. + * SATA phy-reset host port using DET bits of SControl register. + * This function is to be used as standard callback for + * ata_drive_*_reset(). * - * LOCKING: None. + * LOCKING: + * Kernel thread context (may sleep) * + * RETURNS: + * 0 on success, -errno otherwise. */ - -static unsigned int ata_busy_sleep (struct ata_port *ap, - unsigned long tmout_pat, - unsigned long tmout) +int sata_std_hardreset(struct ata_port *ap, int verbose, unsigned int *class) { - unsigned long timer_start, timeout; - u8 status; + DPRINTK("ENTER\n"); - status = ata_busy_wait(ap, ATA_BUSY, 300); - timer_start = jiffies; - timeout = timer_start + tmout_pat; - while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { - msleep(50); - status = ata_busy_wait(ap, ATA_BUSY, 3); - } + /* Issue phy wake/reset */ + scr_write_flush(ap, SCR_CONTROL, 0x301); - if (status & ATA_BUSY) - printk(KERN_WARNING "ata%u is slow to respond, " - "please be patient\n", ap->id); + /* + * Couldn't find anything in SATA I/II specs, but AHCI-1.1 + * 10.4.2 says at least 1 ms. + */ + msleep(1); - timeout = timer_start + tmout; - while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { - msleep(50); - status = ata_chk_status(ap); + /* Bring phy back */ + sata_phy_resume(ap); + + /* TODO: phy layer with polling, timeouts, etc. */ + if (!sata_dev_present(ap)) { + *class = ATA_DEV_NONE; + DPRINTK("EXIT, link offline\n"); + return 0; } - if (status & ATA_BUSY) { - printk(KERN_ERR "ata%u failed to respond (%lu secs)\n", - ap->id, tmout / HZ); - return 1; + if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { + if (verbose) + printk(KERN_ERR "ata%u: COMRESET failed " + "(device not ready)\n", ap->id); + else + DPRINTK("EXIT, device not ready\n"); + return -EIO; } + ap->ops->dev_select(ap, 0); /* probably unnecessary */ + + *class = ata_dev_try_classify(ap, 0, NULL); + + DPRINTK("EXIT, class=%u\n", *class); return 0; } -static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) +/** + * ata_std_postreset - standard postreset callback + * @ap: the target ata_port + * @classes: classes of attached devices + * + * This function is invoked after a successful reset. Note that + * the device might have been reset more than once using + * different reset methods before postreset is invoked. + * + * This function is to be used as standard callback for + * ata_drive_*_reset(). + * + * LOCKING: + * Kernel thread context (may sleep) + */ +void ata_std_postreset(struct ata_port *ap, unsigned int *classes) { - struct ata_ioports *ioaddr = &ap->ioaddr; - unsigned int dev0 = devmask & (1 << 0); - unsigned int dev1 = devmask & (1 << 1); - unsigned long timeout; + DPRINTK("ENTER\n"); - /* if device 0 was found in ata_devchk, wait for its - * BSY bit to clear - */ - if (dev0) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + /* set cable type if it isn't already set */ + if (ap->cbl == ATA_CBL_NONE && ap->flags & ATA_FLAG_SATA) + ap->cbl = ATA_CBL_SATA; - /* if device 1 was found in ata_devchk, wait for - * register access, then wait for BSY to clear - */ - timeout = jiffies + ATA_TMOUT_BOOT; - while (dev1) { - u8 nsect, lbal; + /* print link status */ + if (ap->cbl == ATA_CBL_SATA) + sata_print_link_status(ap); - ap->ops->dev_select(ap, 1); - if (ap->flags & ATA_FLAG_MMIO) { - nsect = readb((void __iomem *) ioaddr->nsect_addr); - lbal = readb((void __iomem *) ioaddr->lbal_addr); - } else { - nsect = inb(ioaddr->nsect_addr); - lbal = inb(ioaddr->lbal_addr); - } - if ((nsect == 1) && (lbal == 1)) - break; - if (time_after(jiffies, timeout)) { - dev1 = 0; - break; - } - msleep(50); /* give drive a breather */ - } - if (dev1) - ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + /* re-enable interrupts */ + if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ + ata_irq_on(ap); - /* is all this really necessary? */ - ap->ops->dev_select(ap, 0); - if (dev1) + /* is double-select really necessary? */ + if (classes[0] != ATA_DEV_NONE) ap->ops->dev_select(ap, 1); - if (dev0) + if (classes[1] != ATA_DEV_NONE) ap->ops->dev_select(ap, 0); + + /* bail out if no device is present */ + if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) { + DPRINTK("EXIT, no device\n"); + return; + } + + /* set up device control */ + if (ap->ioaddr.ctl_addr) { + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr); + else + outb(ap->ctl, ap->ioaddr.ctl_addr); + } + + DPRINTK("EXIT\n"); } /** - * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. - * @ap: Port to reset and probe + * ata_std_probe_reset - standard probe reset method + * @ap: prot to perform probe-reset + * @classes: resulting classes of attached devices * - * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and - * probe the bus. Not often used these days. + * The stock off-the-shelf ->probe_reset method. * * LOCKING: - * PCI/etc. bus probe sem. + * Kernel thread context (may sleep) * + * RETURNS: + * 0 on success, -errno otherwise. */ +int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes) +{ + ata_reset_fn_t hardreset; + + hardreset = NULL; + if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) + hardreset = sata_std_hardreset; + + return ata_drive_probe_reset(ap, ata_std_probeinit, + ata_std_softreset, hardreset, + ata_std_postreset, classes); +} -static unsigned int ata_bus_edd(struct ata_port *ap) +static int do_probe_reset(struct ata_port *ap, ata_reset_fn_t reset, + ata_postreset_fn_t postreset, + unsigned int *classes) { - struct ata_taskfile tf; + int i, rc; - /* 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; + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_UNKNOWN; - /* do bus reset */ - ata_tf_to_host(ap, &tf); + rc = reset(ap, 0, classes); + if (rc) + return rc; - /* spec says at least 2ms. but who knows with those - * crazy ATAPI devices... + /* If any class isn't ATA_DEV_UNKNOWN, consider classification + * is complete and convert all ATA_DEV_UNKNOWN to + * ATA_DEV_NONE. */ - msleep(150); + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] != ATA_DEV_UNKNOWN) + break; + + if (i < ATA_MAX_DEVICES) + for (i = 0; i < ATA_MAX_DEVICES; i++) + if (classes[i] == ATA_DEV_UNKNOWN) + classes[i] = ATA_DEV_NONE; - return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); + if (postreset) + postreset(ap, classes); + + return classes[0] != ATA_DEV_UNKNOWN ? 0 : -ENODEV; } -static unsigned int ata_bus_softreset(struct ata_port *ap, - unsigned int devmask) +/** + * ata_drive_probe_reset - Perform probe reset with given methods + * @ap: port to reset + * @probeinit: probeinit method (can be NULL) + * @softreset: softreset method (can be NULL) + * @hardreset: hardreset method (can be NULL) + * @postreset: postreset method (can be NULL) + * @classes: resulting classes of attached devices + * + * Reset the specified port and classify attached devices using + * given methods. This function prefers softreset but tries all + * possible reset sequences to reset and classify devices. This + * function is intended to be used for constructing ->probe_reset + * callback by low level drivers. + * + * Reset methods should follow the following rules. + * + * - Return 0 on sucess, -errno on failure. + * - If classification is supported, fill classes[] with + * recognized class codes. + * - If classification is not supported, leave classes[] alone. + * - If verbose is non-zero, print error message on failure; + * otherwise, shut up. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, -EINVAL if no reset method is avaliable, -ENODEV + * if classification fails, and any error code from reset + * methods. + */ +int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, + ata_reset_fn_t softreset, ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset, unsigned int *classes) { - struct ata_ioports *ioaddr = &ap->ioaddr; + int rc = -EINVAL; - DPRINTK("ata%u: bus reset via SRST\n", ap->id); + if (probeinit) + probeinit(ap); - /* software reset. causes dev0 to be selected */ - if (ap->flags & ATA_FLAG_MMIO) { - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - udelay(20); /* FIXME: flush */ - writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr); - udelay(20); /* FIXME: flush */ - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - } else { - outb(ap->ctl, ioaddr->ctl_addr); - udelay(10); - outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr); - udelay(10); - outb(ap->ctl, ioaddr->ctl_addr); + if (softreset) { + rc = do_probe_reset(ap, softreset, postreset, classes); + if (rc == 0) + return 0; } - /* spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - */ - msleep(150); + if (!hardreset) + return rc; + + rc = do_probe_reset(ap, hardreset, postreset, classes); + if (rc == 0 || rc != -ENODEV) + return rc; - ata_bus_post_reset(ap, devmask); + if (softreset) + rc = do_probe_reset(ap, softreset, postreset, classes); - return 0; + return rc; } /** - * ata_bus_reset - reset host port and associated ATA channel - * @ap: port to reset + * ata_dev_same_device - Determine whether new ID matches configured device + * @ap: port on which the device to compare against resides + * @dev: device to compare against + * @new_class: class of the new device + * @new_id: IDENTIFY page of the new device * - * This is typically the first time we actually start issuing - * commands to the ATA channel. We wait for BSY to clear, then - * issue EXECUTE DEVICE DIAGNOSTIC command, polling for its - * result. Determine what devices, if any, are on the channel - * by looking at the device 0/1 error register. Look at the signature - * stored in each device's taskfile registers, to determine if - * the device is ATA or ATAPI. + * Compare @new_class and @new_id against @dev and determine + * whether @dev is the device indicated by @new_class and + * @new_id. * * LOCKING: - * PCI/etc. bus probe sem. - * Obtains host_set lock. + * None. * - * SIDE EFFECTS: - * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. + * RETURNS: + * 1 if @dev matches @new_class and @new_id, 0 otherwise. */ - -void ata_bus_reset(struct ata_port *ap) +static int ata_dev_same_device(struct ata_port *ap, struct ata_device *dev, + unsigned int new_class, const u16 *new_id) { - 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; + const u16 *old_id = dev->id; + unsigned char model[2][41], serial[2][21]; + u64 new_n_sectors; + + if (dev->class != new_class) { + printk(KERN_INFO + "ata%u: dev %u class mismatch %d != %d\n", + ap->id, dev->devno, dev->class, new_class); + return 0; + } - DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); + ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0])); + ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1])); + ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0])); + ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1])); + new_n_sectors = ata_id_n_sectors(new_id); - /* determine if device 0/1 are present */ - if (ap->flags & ATA_FLAG_SATA_RESET) - dev0 = 1; - else { - dev0 = ata_devchk(ap, 0); - if (slave_possible) - dev1 = ata_devchk(ap, 1); + if (strcmp(model[0], model[1])) { + printk(KERN_INFO + "ata%u: dev %u model number mismatch '%s' != '%s'\n", + ap->id, dev->devno, model[0], model[1]); + return 0; } - if (dev0) - devmask |= (1 << 0); - if (dev1) - devmask |= (1 << 1); - - /* select device 0 again */ - ap->ops->dev_select(ap, 0); + if (strcmp(serial[0], serial[1])) { + printk(KERN_INFO + "ata%u: dev %u serial number mismatch '%s' != '%s'\n", + ap->id, dev->devno, serial[0], serial[1]); + return 0; + } - /* 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 (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) { + printk(KERN_INFO + "ata%u: dev %u n_sectors mismatch %llu != %llu\n", + ap->id, dev->devno, (unsigned long long)dev->n_sectors, + (unsigned long long)new_n_sectors); + return 0; } - if (rc) - goto err_out; + return 1; +} - /* - * determine by signature whether we have ATA or ATAPI devices - */ - err = ata_dev_try_classify(ap, 0); - if ((slave_possible) && (err != 0x81)) - ata_dev_try_classify(ap, 1); +/** + * ata_dev_revalidate - Revalidate ATA device + * @ap: port on which the device to revalidate resides + * @dev: device to revalidate + * @post_reset: is this revalidation after reset? + * + * Re-read IDENTIFY page and make sure @dev is still attached to + * the port. + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, negative errno otherwise + */ +int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, + int post_reset) +{ + unsigned int class; + u16 *id; + int rc; - /* re-enable interrupts */ - if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ - ata_irq_on(ap); + if (!ata_dev_present(dev)) + return -ENODEV; - /* is double-select really necessary? */ - if (ap->device[1].class != ATA_DEV_NONE) - ap->ops->dev_select(ap, 1); - if (ap->device[0].class != ATA_DEV_NONE) - ap->ops->dev_select(ap, 0); + class = dev->class; + id = NULL; - /* if no devices were detected, disable this port */ - if ((ap->device[0].class == ATA_DEV_NONE) && - (ap->device[1].class == ATA_DEV_NONE)) - goto err_out; + /* allocate & read ID data */ + rc = ata_dev_read_id(ap, dev, &class, post_reset, &id); + if (rc) + goto fail; - if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { - /* set up device control for ATA_FLAG_SATA_RESET */ - if (ap->flags & ATA_FLAG_MMIO) - writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); - else - outb(ap->ctl, ioaddr->ctl_addr); + /* is the device still there? */ + if (!ata_dev_same_device(ap, dev, class, id)) { + rc = -ENODEV; + goto fail; } - DPRINTK("EXIT\n"); - return; - -err_out: - printk(KERN_ERR "ata%u: disabling port\n", ap->id); - ap->ops->port_disable(ap); + kfree(dev->id); + dev->id = id; - DPRINTK("EXIT\n"); -} + /* configure device according to the new ID */ + return ata_dev_configure(ap, dev, 0); -static void ata_pr_blacklisted(struct ata_port *ap, struct ata_device *dev) -{ - printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, disabling DMA\n", - ap->id, dev->devno); + fail: + printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n", + ap->id, dev->devno, rc); + kfree(id); + return rc; } -static const char * ata_dma_blacklist [] = { - "WDC AC11000H", - "WDC AC22100H", - "WDC AC32500H", - "WDC AC33100H", - "WDC AC31600H", - "WDC AC32100H", - "WDC AC23200L", - "Compaq CRD-8241B", - "CRD-8400B", - "CRD-8480B", - "CRD-8482B", - "CRD-84", - "SanDisk SDP3B", - "SanDisk SDP3B-64", - "SANYO CD-ROM CRD", - "HITACHI CDR-8", - "HITACHI CDR-8335", - "HITACHI CDR-8435", - "Toshiba CD-ROM XM-6202B", - "TOSHIBA CD-ROM XM-1702BC", - "CD-532E-A", - "E-IDE CD-ROM CR-840", - "CD-ROM Drive/F5A", - "WPI CDD-820", - "SAMSUNG CD-ROM SC-148C", - "SAMSUNG CD-ROM SC", - "SanDisk SDP3B-64", - "ATAPI CD-ROM DRIVE 40X MAXIMUM", - "_NEC DV5800A", +static const char * const ata_dma_blacklist [] = { + "WDC AC11000H", NULL, + "WDC AC22100H", NULL, + "WDC AC32500H", NULL, + "WDC AC33100H", NULL, + "WDC AC31600H", NULL, + "WDC AC32100H", "24.09P07", + "WDC AC23200L", "21.10N21", + "Compaq CRD-8241B", NULL, + "CRD-8400B", NULL, + "CRD-8480B", NULL, + "CRD-8482B", NULL, + "CRD-84", NULL, + "SanDisk SDP3B", NULL, + "SanDisk SDP3B-64", NULL, + "SANYO CD-ROM CRD", NULL, + "HITACHI CDR-8", NULL, + "HITACHI CDR-8335", NULL, + "HITACHI CDR-8435", NULL, + "Toshiba CD-ROM XM-6202B", NULL, + "TOSHIBA CD-ROM XM-1702BC", NULL, + "CD-532E-A", NULL, + "E-IDE CD-ROM CR-840", NULL, + "CD-ROM Drive/F5A", NULL, + "WPI CDD-820", NULL, + "SAMSUNG CD-ROM SC-148C", NULL, + "SAMSUNG CD-ROM SC", NULL, + "SanDisk SDP3B-64", NULL, + "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, + "_NEC DV5800A", NULL, + "SAMSUNG CD-ROM SN-124", "N001" }; -static int ata_dma_blacklisted(struct ata_port *ap, struct ata_device *dev) +static int ata_strim(char *s, size_t len) { - unsigned char model_num[40]; - char *s; - unsigned int len; - int i; - - ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS, - sizeof(model_num)); - s = &model_num[0]; - len = strnlen(s, sizeof(model_num)); + len = strnlen(s, len); /* ATAPI specifies that empty space is blank-filled; remove blanks */ while ((len > 0) && (s[len - 1] == ' ')) { len--; s[len] = 0; } - - for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i++) - if (!strncmp(ata_dma_blacklist[i], s, len)) - return 1; - - return 0; + return len; } -static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift) +static int ata_dma_blacklisted(const struct ata_device *dev) { - struct ata_device *master, *slave; - unsigned int mask; - - master = &ap->device[0]; - slave = &ap->device[1]; - - assert (ata_dev_present(master) || ata_dev_present(slave)); + unsigned char model_num[40]; + unsigned char model_rev[16]; + unsigned int nlen, rlen; + int i; - if (shift == ATA_SHIFT_UDMA) { - mask = ap->udma_mask; - if (ata_dev_present(master)) { - mask &= (master->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dma_blacklisted(ap, master)) { - mask = 0; - ata_pr_blacklisted(ap, master); - } - } - if (ata_dev_present(slave)) { - mask &= (slave->id[ATA_ID_UDMA_MODES] & 0xff); - if (ata_dma_blacklisted(ap, slave)) { - mask = 0; - ata_pr_blacklisted(ap, slave); - } - } - } - 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_dma_blacklisted(ap, master)) { - mask = 0; - ata_pr_blacklisted(ap, master); - } - } - if (ata_dev_present(slave)) { - mask &= (slave->id[ATA_ID_MWDMA_MODES] & 0x07); - if (ata_dma_blacklisted(ap, slave)) { - mask = 0; - ata_pr_blacklisted(ap, slave); - } - } - } - 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; + ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, + sizeof(model_num)); + ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS, + sizeof(model_rev)); + nlen = ata_strim(model_num, sizeof(model_num)); + rlen = ata_strim(model_rev, sizeof(model_rev)); + + for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { + if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { + if (ata_dma_blacklist[i+1] == NULL) + return 1; + if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) + return 1; } } - else { - mask = 0xffffffff; /* shut up compiler warning */ - BUG(); - } - - return mask; -} - -/* find greatest bit */ -static int fgb(u32 bitmap) -{ - unsigned int i; - int x = -1; - - for (i = 0; i < 32; i++) - if (bitmap & (1 << i)) - x = i; - - return x; + return 0; } /** - * ata_choose_xfer_mode - attempt to find best transfer mode - * @ap: Port for which an xfer mode will be selected - * @xfer_mode_out: (output) SET FEATURES - XFER MODE code - * @xfer_shift_out: (output) bit shift that selects this mode + * ata_dev_xfermask - Compute supported xfermask of the given device + * @ap: Port on which the device to compute xfermask for resides + * @dev: Device to compute xfermask for * - * Based on host and device capabilities, determine the - * maximum transfer mode that is amenable to all. + * Compute supported xfermask of @dev and store it in + * dev->*_mask. This function is responsible for applying all + * known limits including host controller limits, device + * blacklist, etc... * - * LOCKING: - * PCI/etc. bus probe sem. + * 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. * - * RETURNS: - * Zero on success, negative on error. + * LOCKING: + * None. */ - -static int ata_choose_xfer_mode(struct ata_port *ap, - u8 *xfer_mode_out, - unsigned int *xfer_shift_out) +static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) { - unsigned int mask, shift; - int x, i; + struct ata_host_set *hs = ap->host_set; + unsigned long xfer_mask; + int i; - for (i = 0; i < ARRAY_SIZE(xfer_mode_classes); i++) { - shift = xfer_mode_classes[i].shift; - mask = ata_get_mode_mask(ap, shift); + xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, + ap->udma_mask); - x = fgb(mask); - if (x >= 0) { - *xfer_mode_out = xfer_mode_classes[i].base + x; - *xfer_shift_out = shift; - return 0; - } + /* 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)) + continue; + xfer_mask &= ata_pack_xfermask(d->pio_mask, d->mwdma_mask, + d->udma_mask); + 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); } - return -1; + 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); } /** @@ -2107,40 +2711,73 @@ static int ata_choose_xfer_mode(struct ata_port *ap, * * LOCKING: * PCI/etc. bus probe sem. + * + * RETURNS: + * 0 on success, AC_ERR_* mask otherwise. */ -static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) +static unsigned int ata_dev_set_xfermode(struct ata_port *ap, + struct ata_device *dev) { - DECLARE_COMPLETION(wait); - struct ata_queued_cmd *qc; - int rc; - unsigned long flags; + struct ata_taskfile tf; + unsigned int err_mask; /* set up set-features taskfile */ DPRINTK("set features - xfer mode\n"); - qc = ata_qc_new_init(ap, dev); - BUG_ON(qc == NULL); + ata_tf_init(ap, &tf, dev->devno); + tf.command = ATA_CMD_SET_FEATURES; + tf.feature = SETFEATURES_XFER; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_NODATA; + tf.nsect = dev->xfer_mode; - qc->tf.command = ATA_CMD_SET_FEATURES; - qc->tf.feature = SETFEATURES_XFER; - qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - qc->tf.protocol = ATA_PROT_NODATA; - qc->tf.nsect = dev->xfer_mode; + err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); - qc->waiting = &wait; - qc->complete_fn = ata_qc_complete_noop; + DPRINTK("EXIT, err_mask=%x\n", err_mask); + return err_mask; +} - spin_lock_irqsave(&ap->host_set->lock, flags); - rc = ata_qc_issue(qc); - spin_unlock_irqrestore(&ap->host_set->lock, flags); +/** + * ata_dev_init_params - Issue INIT DEV PARAMS command + * @ap: Port associated with device @dev + * @dev: Device to which command will be sent + * @heads: Number of heads (taskfile parameter) + * @sectors: Number of sectors (taskfile parameter) + * + * LOCKING: + * Kernel thread context (may sleep) + * + * RETURNS: + * 0 on success, AC_ERR_* mask otherwise. + */ - if (rc) - ata_port_disable(ap); - else - wait_for_completion(&wait); +static unsigned int ata_dev_init_params(struct ata_port *ap, + struct ata_device *dev, + u16 heads, + u16 sectors) +{ + struct ata_taskfile tf; + unsigned int err_mask; - DPRINTK("EXIT\n"); + /* Number of sectors per track 1-255. Number of heads 1-16 */ + if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) + return AC_ERR_INVALID; + + /* set up init dev params taskfile */ + DPRINTK("init dev params \n"); + + ata_tf_init(ap, &tf, dev->devno); + tf.command = ATA_CMD_INIT_DEV_PARAMS; + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_NODATA; + tf.nsect = sectors; + tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ + + err_mask = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); + + DPRINTK("EXIT, err_mask=%x\n", err_mask); + return err_mask; } /** @@ -2156,25 +2793,50 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) static void ata_sg_clean(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; int dir = qc->dma_dir; + void *pad_buf = NULL; - assert(qc->flags & ATA_QCFLAG_DMAMAP); - assert(sg != NULL); + WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP)); + WARN_ON(sg == NULL); if (qc->flags & ATA_QCFLAG_SINGLE) - assert(qc->n_elem == 1); + WARN_ON(qc->n_elem > 1); - DPRINTK("unmapping %u sg elements\n", qc->n_elem); + VPRINTK("unmapping %u sg elements\n", qc->n_elem); - if (qc->flags & ATA_QCFLAG_SG) - dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); - else - dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]), - sg_dma_len(&sg[0]), dir); + /* if we padded the buffer out to 32-bit bound, and data + * xfer direction is from-device, we must copy from the + * pad buffer back into the supplied buffer + */ + if (qc->pad_len && !(qc->tf.flags & ATA_TFLAG_WRITE)) + pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + + if (qc->flags & ATA_QCFLAG_SG) { + if (qc->n_elem) + dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); + /* restore last sg */ + sg[qc->orig_n_elem - 1].length += qc->pad_len; + if (pad_buf) { + struct scatterlist *psg = &qc->pad_sgent; + void *addr = kmap_atomic(psg->page, KM_IRQ0); + memcpy(addr + psg->offset, pad_buf, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); + } + } else { + if (qc->n_elem) + dma_unmap_single(ap->dev, + sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), + dir); + /* restore sg */ + sg->length += qc->pad_len; + if (pad_buf) + memcpy(qc->buf_virt + sg->length - qc->pad_len, + pad_buf, qc->pad_len); + } qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->sg = NULL; + qc->__sg = NULL; } /** @@ -2190,15 +2852,15 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) */ static void ata_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; - unsigned int idx, nelem; + struct scatterlist *sg; + unsigned int idx; - assert(sg != NULL); - assert(qc->n_elem > 0); + WARN_ON(qc->__sg == NULL); + WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); idx = 0; - for (nelem = qc->n_elem; nelem; nelem--,sg++) { + ata_for_each_sg(sg, qc) { u32 addr, offset; u32 sg_len, len; @@ -2269,6 +2931,8 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ata_fill_sg(qc); } +void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } + /** * ata_sg_init_one - Associate command with memory buffer * @qc: Command to be associated @@ -2289,14 +2953,13 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) qc->flags |= ATA_QCFLAG_SINGLE; memset(&qc->sgent, 0, sizeof(qc->sgent)); - qc->sg = &qc->sgent; + qc->__sg = &qc->sgent; qc->n_elem = 1; + qc->orig_n_elem = 1; qc->buf_virt = buf; - sg = qc->sg; - sg->page = virt_to_page(buf); - sg->offset = (unsigned long) buf & ~PAGE_MASK; - sg->length = buflen; + sg = qc->__sg; + sg_init_one(sg, buf, buflen); } /** @@ -2317,8 +2980,9 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { qc->flags |= ATA_QCFLAG_SG; - qc->sg = sg; + qc->__sg = sg; qc->n_elem = n_elem; + qc->orig_n_elem = n_elem; } /** @@ -2338,17 +3002,52 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; int dir = qc->dma_dir; - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; dma_addr_t dma_address; + int trim_sg = 0; + + /* we must lengthen transfers to end on a 32-bit boundary */ + qc->pad_len = sg->length & 3; + if (qc->pad_len) { + void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + struct scatterlist *psg = &qc->pad_sgent; - dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, + WARN_ON(qc->dev->class != ATA_DEV_ATAPI); + + memset(pad_buf, 0, ATA_DMA_PAD_SZ); + + if (qc->tf.flags & ATA_TFLAG_WRITE) + memcpy(pad_buf, qc->buf_virt + sg->length - qc->pad_len, + qc->pad_len); + + sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + sg_dma_len(psg) = ATA_DMA_PAD_SZ; + /* trim sg */ + sg->length -= qc->pad_len; + if (sg->length == 0) + trim_sg = 1; + + DPRINTK("padding done, sg->length=%u pad_len=%u\n", + sg->length, qc->pad_len); + } + + if (trim_sg) { + qc->n_elem--; + goto skip_map; + } + + dma_address = dma_map_single(ap->dev, qc->buf_virt, sg->length, dir); - if (dma_mapping_error(dma_address)) + if (dma_mapping_error(dma_address)) { + /* restore sg */ + sg->length += qc->pad_len; return -1; + } sg_dma_address(sg) = dma_address; sg_dma_len(sg) = sg->length; +skip_map: DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); @@ -2372,19 +3071,69 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) static int ata_sg_setup(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - struct scatterlist *sg = qc->sg; - int n_elem, dir; + struct scatterlist *sg = qc->__sg; + struct scatterlist *lsg = &sg[qc->n_elem - 1]; + int n_elem, pre_n_elem, dir, trim_sg = 0; VPRINTK("ENTER, ata%u\n", ap->id); - assert(qc->flags & ATA_QCFLAG_SG); + WARN_ON(!(qc->flags & ATA_QCFLAG_SG)); + + /* we must lengthen transfers to end on a 32-bit boundary */ + qc->pad_len = lsg->length & 3; + if (qc->pad_len) { + void *pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); + struct scatterlist *psg = &qc->pad_sgent; + unsigned int offset; + + WARN_ON(qc->dev->class != ATA_DEV_ATAPI); + + memset(pad_buf, 0, ATA_DMA_PAD_SZ); + + /* + * psg->page/offset are used to copy to-be-written + * data in this function or read data in ata_sg_clean. + */ + offset = lsg->offset + lsg->length - qc->pad_len; + psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT); + psg->offset = offset_in_page(offset); + + if (qc->tf.flags & ATA_TFLAG_WRITE) { + void *addr = kmap_atomic(psg->page, KM_IRQ0); + memcpy(pad_buf, addr + psg->offset, qc->pad_len); + kunmap_atomic(addr, KM_IRQ0); + } + + sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); + sg_dma_len(psg) = ATA_DMA_PAD_SZ; + /* trim last sg */ + lsg->length -= qc->pad_len; + if (lsg->length == 0) + trim_sg = 1; + + DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", + qc->n_elem - 1, lsg->length, qc->pad_len); + } + + pre_n_elem = qc->n_elem; + if (trim_sg && pre_n_elem) + pre_n_elem--; + + if (!pre_n_elem) { + n_elem = 0; + goto skip_map; + } dir = qc->dma_dir; - n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir); - if (n_elem < 1) + n_elem = dma_map_sg(ap->dev, sg, pre_n_elem, dir); + if (n_elem < 1) { + /* restore last sg */ + lsg->length += qc->pad_len; return -1; + } DPRINTK("%d sg elements mapped\n", n_elem); +skip_map: qc->n_elem = n_elem; return 0; @@ -2393,13 +3142,13 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) /** * ata_poll_qc_complete - turn irq back on and finish qc * @qc: Command to complete - * @drv_stat: ATA status register content + * @err_mask: ATA status register content * * LOCKING: * None. (grabs host lock) */ -void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) +void ata_poll_qc_complete(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; unsigned long flags; @@ -2407,38 +3156,41 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_NOINTR; ata_irq_on(ap); - ata_qc_complete(qc, drv_stat); + ata_qc_complete(qc); spin_unlock_irqrestore(&ap->host_set->lock, flags); } /** - * ata_pio_poll - - * @ap: + * ata_pio_poll - poll using PIO, depending on current state + * @ap: the target ata_port * * LOCKING: * None. (executing in kernel thread context) * * RETURNS: - * + * timeout value to use */ static unsigned long ata_pio_poll(struct ata_port *ap) { + struct ata_queued_cmd *qc; u8 status; - unsigned int poll_state = PIO_ST_UNKNOWN; - unsigned int reg_state = PIO_ST_UNKNOWN; - const unsigned int tmout_state = PIO_ST_TMOUT; - - switch (ap->pio_task_state) { - case PIO_ST: - case PIO_ST_POLL: - poll_state = PIO_ST_POLL; - reg_state = PIO_ST; + unsigned int poll_state = HSM_ST_UNKNOWN; + unsigned int reg_state = HSM_ST_UNKNOWN; + + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + + switch (ap->hsm_task_state) { + case HSM_ST: + case HSM_ST_POLL: + poll_state = HSM_ST_POLL; + reg_state = HSM_ST; break; - case PIO_ST_LAST: - case PIO_ST_LAST_POLL: - poll_state = PIO_ST_LAST_POLL; - reg_state = PIO_ST_LAST; + case HSM_ST_LAST: + case HSM_ST_LAST_POLL: + poll_state = HSM_ST_LAST_POLL; + reg_state = HSM_ST_LAST; break; default: BUG(); @@ -2448,20 +3200,21 @@ static unsigned long ata_pio_poll(struct ata_port *ap) status = ata_chk_status(ap); if (status & ATA_BUSY) { if (time_after(jiffies, ap->pio_task_timeout)) { - ap->pio_task_state = tmout_state; + qc->err_mask |= AC_ERR_TIMEOUT; + ap->hsm_task_state = HSM_ST_TMOUT; return 0; } - ap->pio_task_state = poll_state; + ap->hsm_task_state = poll_state; return ATA_SHORT_PAUSE; } - ap->pio_task_state = reg_state; + ap->hsm_task_state = reg_state; return 0; } /** - * ata_pio_complete - - * @ap: + * ata_pio_complete - check if drive is busy or idle + * @ap: the target ata_port * * LOCKING: * None. (executing in kernel thread context) @@ -2480,31 +3233,33 @@ static int ata_pio_complete (struct ata_port *ap) * we enter, BSY will be cleared in a chk-status or two. If not, * the drive is probably seeking or something. Snooze for a couple * msecs, then chk-status again. If still busy, fall back to - * PIO_ST_POLL state. + * HSM_ST_POLL state. */ - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); - if (drv_stat & (ATA_BUSY | ATA_DRQ)) { + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { msleep(2); - drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); - if (drv_stat & (ATA_BUSY | ATA_DRQ)) { - ap->pio_task_state = PIO_ST_LAST_POLL; + drv_stat = ata_busy_wait(ap, ATA_BUSY, 10); + if (drv_stat & ATA_BUSY) { + ap->hsm_task_state = HSM_ST_LAST_POLL; ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; return 0; } } + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + drv_stat = ata_wait_idle(ap); if (!ata_ok(drv_stat)) { - ap->pio_task_state = PIO_ST_ERR; + qc->err_mask |= __ac_err_mask(drv_stat); + ap->hsm_task_state = HSM_ST_ERR; return 0; } - qc = ata_qc_from_tag(ap, ap->active_tag); - assert(qc != NULL); - - ap->pio_task_state = PIO_ST_IDLE; + ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, drv_stat); + WARN_ON(qc->err_mask); + ata_poll_qc_complete(qc); /* another command may start at this point */ @@ -2513,7 +3268,7 @@ static int ata_pio_complete (struct ata_port *ap) /** - * swap_buf_le16 - + * swap_buf_le16 - swap halves of 16-bit words in place * @buf: Buffer to swap * @buf_words: Number of 16-bit words in buffer. * @@ -2522,6 +3277,7 @@ static int ata_pio_complete (struct ata_port *ap) * vice-versa. * * LOCKING: + * Inherited from caller. */ void swap_buf_le16(u16 *buf, unsigned int buf_words) { @@ -2544,7 +3300,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) * * LOCKING: * Inherited from caller. - * */ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, @@ -2590,7 +3345,6 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, * * LOCKING: * Inherited from caller. - * */ static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, @@ -2630,16 +3384,26 @@ static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, * * LOCKING: * Inherited from caller. - * */ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, unsigned int buflen, int do_write) { - if (ap->flags & ATA_FLAG_MMIO) - ata_mmio_data_xfer(ap, buf, buflen, do_write); - else - ata_pio_data_xfer(ap, buf, buflen, do_write); + /* Make the crap hardware pay the costs not the good stuff */ + if (unlikely(ap->flags & ATA_FLAG_IRQ_MASK)) { + unsigned long flags; + local_irq_save(flags); + if (ap->flags & ATA_FLAG_MMIO) + ata_mmio_data_xfer(ap, buf, buflen, do_write); + else + ata_pio_data_xfer(ap, buf, buflen, do_write); + local_irq_restore(flags); + } else { + if (ap->flags & ATA_FLAG_MMIO) + ata_mmio_data_xfer(ap, buf, buflen, do_write); + else + ata_pio_data_xfer(ap, buf, buflen, do_write); + } } /** @@ -2655,14 +3419,14 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, static void ata_pio_sector(struct ata_queued_cmd *qc) { int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; struct ata_port *ap = qc->ap; struct page *page; unsigned int offset; unsigned char *buf; if (qc->cursect == (qc->nsect - 1)) - ap->pio_task_state = PIO_ST_LAST; + ap->hsm_task_state = HSM_ST_LAST; page = sg[qc->cursg].page; offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE; @@ -2705,14 +3469,14 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) { int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); - struct scatterlist *sg = qc->sg; + struct scatterlist *sg = qc->__sg; struct ata_port *ap = qc->ap; struct page *page; unsigned char *buf; unsigned int offset, count; if (qc->curbytes + bytes >= qc->nbytes) - ap->pio_task_state = PIO_ST_LAST; + ap->hsm_task_state = HSM_ST_LAST; next_sg: if (unlikely(qc->cursg >= qc->n_elem)) { @@ -2734,11 +3498,11 @@ next_sg: for (i = 0; i < words; i++) ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); - ap->pio_task_state = PIO_ST_LAST; + ap->hsm_task_state = HSM_ST_LAST; return; } - sg = &qc->sg[qc->cursg]; + sg = &qc->__sg[qc->cursg]; page = sg->page; offset = sg->offset + qc->cursg_ofs; @@ -2783,7 +3547,6 @@ next_sg: * * LOCKING: * Inherited from caller. - * */ static void atapi_pio_bytes(struct ata_queued_cmd *qc) @@ -2815,12 +3578,13 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) err_out: printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n", ap->id, dev->devno); - ap->pio_task_state = PIO_ST_ERR; + qc->err_mask |= AC_ERR_HSM; + ap->hsm_task_state = HSM_ST_ERR; } /** - * ata_pio_sector - - * @ap: + * ata_pio_block - start PIO on a block + * @ap: the target ata_port * * LOCKING: * None. (executing in kernel thread context) @@ -2832,31 +3596,39 @@ static void ata_pio_block(struct ata_port *ap) u8 status; /* - * This is purely hueristic. This is a fast path. + * This is purely heuristic. This is a fast path. * Sometimes when we enter, BSY will be cleared in * a chk-status or two. If not, the drive is probably seeking * or something. Snooze for a couple msecs, then * chk-status again. If still busy, fall back to - * PIO_ST_POLL state. + * HSM_ST_POLL state. */ status = ata_busy_wait(ap, ATA_BUSY, 5); if (status & ATA_BUSY) { msleep(2); status = ata_busy_wait(ap, ATA_BUSY, 10); if (status & ATA_BUSY) { - ap->pio_task_state = PIO_ST_POLL; + ap->hsm_task_state = HSM_ST_POLL; ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; return; } } qc = ata_qc_from_tag(ap, ap->active_tag); - assert(qc != NULL); + WARN_ON(qc == NULL); + + /* check error */ + if (status & (ATA_ERR | ATA_DF)) { + qc->err_mask |= AC_ERR_DEV; + ap->hsm_task_state = HSM_ST_ERR; + return; + } + /* transfer data if any */ if (is_atapi_taskfile(&qc->tf)) { - /* no more data to transfer or unsupported ATAPI command */ + /* DRQ=0 means no more data to transfer */ if ((status & ATA_DRQ) == 0) { - ap->pio_task_state = PIO_ST_LAST; + ap->hsm_task_state = HSM_ST_LAST; return; } @@ -2864,29 +3636,35 @@ static void ata_pio_block(struct ata_port *ap) } else { /* handle BSY=0, DRQ=0 as error */ if ((status & ATA_DRQ) == 0) { - ap->pio_task_state = PIO_ST_ERR; + qc->err_mask |= AC_ERR_HSM; + ap->hsm_task_state = HSM_ST_ERR; return; } ata_pio_sector(qc); } + + ata_altstatus(ap); /* flush */ } static void ata_pio_error(struct ata_port *ap) { struct ata_queued_cmd *qc; - u8 drv_stat; qc = ata_qc_from_tag(ap, ap->active_tag); - assert(qc != NULL); + WARN_ON(qc == NULL); + + if (qc->tf.command != ATA_CMD_PACKET) + printk(KERN_WARNING "ata%u: PIO error\n", ap->id); - drv_stat = ata_chk_status(ap); - printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", - ap->id, drv_stat); + /* make sure qc->err_mask is available to + * know what's wrong and recover + */ + WARN_ON(qc->err_mask == 0); - ap->pio_task_state = PIO_ST_IDLE; + ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, drv_stat | ATA_ERR); + ata_poll_qc_complete(qc); } static void ata_pio_task(void *_data) @@ -2899,79 +3677,108 @@ fsm_start: timeout = 0; qc_completed = 0; - switch (ap->pio_task_state) { - case PIO_ST_IDLE: + switch (ap->hsm_task_state) { + case HSM_ST_IDLE: return; - case PIO_ST: + case HSM_ST: ata_pio_block(ap); break; - case PIO_ST_LAST: + case HSM_ST_LAST: qc_completed = ata_pio_complete(ap); break; - case PIO_ST_POLL: - case PIO_ST_LAST_POLL: + case HSM_ST_POLL: + case HSM_ST_LAST_POLL: timeout = ata_pio_poll(ap); break; - case PIO_ST_TMOUT: - case PIO_ST_ERR: + case HSM_ST_TMOUT: + case HSM_ST_ERR: ata_pio_error(ap); return; } if (timeout) - queue_delayed_work(ata_wq, &ap->pio_task, timeout); + ata_port_queue_task(ap, ata_pio_task, ap, timeout); else if (!qc_completed) goto fsm_start; } -static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd) +/** + * atapi_packet_task - Write CDB bytes to hardware + * @_data: Port to which ATAPI device is attached. + * + * When device has indicated its readiness to accept + * a CDB, this function is called. Send the CDB. + * If DMA is to be performed, exit immediately. + * Otherwise, we are in polling mode, so poll + * status under operation succeeds or fails. + * + * LOCKING: + * Kernel thread context (may sleep) + */ + +static void atapi_packet_task(void *_data) { - DECLARE_COMPLETION(wait); + struct ata_port *ap = _data; struct ata_queued_cmd *qc; - unsigned long flags; - int rc; - - DPRINTK("ATAPI request sense\n"); + u8 status; - qc = ata_qc_new_init(ap, dev); - BUG_ON(qc == NULL); + qc = ata_qc_from_tag(ap, ap->active_tag); + WARN_ON(qc == NULL); + WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); - /* FIXME: is this needed? */ - memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + /* sleep-wait for BSY to clear */ + DPRINTK("busy wait\n"); + if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) { + qc->err_mask |= AC_ERR_TIMEOUT; + goto err_out; + } - ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); - qc->dma_dir = DMA_FROM_DEVICE; + /* make sure DRQ is set */ + status = ata_chk_status(ap); + if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { + qc->err_mask |= AC_ERR_HSM; + goto err_out; + } - memset(&qc->cdb, 0, ap->cdb_len); - qc->cdb[0] = REQUEST_SENSE; - qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; + /* send SCSI cdb */ + DPRINTK("send cdb\n"); + WARN_ON(qc->dev->cdb_len < 12); - qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; - qc->tf.command = ATA_CMD_PACKET; + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || + qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { + unsigned long flags; - qc->tf.protocol = ATA_PROT_ATAPI; - qc->tf.lbam = (8 * 1024) & 0xff; - qc->tf.lbah = (8 * 1024) >> 8; - qc->nbytes = SCSI_SENSE_BUFFERSIZE; + /* Once we're done issuing command and kicking bmdma, + * irq handler takes over. To not lose irq, we need + * to clear NOINTR flag before sending cdb, but + * interrupt handler shouldn't be invoked before we're + * finished. Hence, the following locking. + */ + spin_lock_irqsave(&ap->host_set->lock, flags); + ap->flags &= ~ATA_FLAG_NOINTR; + ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); + ata_altstatus(ap); /* flush */ - qc->waiting = &wait; - qc->complete_fn = ata_qc_complete_noop; + if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) + ap->ops->bmdma_start(qc); /* initiate bmdma */ + spin_unlock_irqrestore(&ap->host_set->lock, flags); + } else { + ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1); + ata_altstatus(ap); /* flush */ - spin_lock_irqsave(&ap->host_set->lock, flags); - rc = ata_qc_issue(qc); - spin_unlock_irqrestore(&ap->host_set->lock, flags); + /* PIO commands are handled by polling */ + ap->hsm_task_state = HSM_ST; + ata_port_queue_task(ap, ata_pio_task, ap, 0); + } - if (rc) - ata_port_disable(ap); - else - wait_for_completion(&wait); + return; - DPRINTK("EXIT\n"); +err_out: + ata_poll_qc_complete(qc); } /** @@ -2997,42 +3804,15 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_host_set *host_set = ap->host_set; - struct ata_device *dev = qc->dev; u8 host_stat = 0, drv_stat; unsigned long flags; DPRINTK("ENTER\n"); - /* FIXME: doesn't this conflict with timeout handling? */ - if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) { - struct scsi_cmnd *cmd = qc->scsicmd; - - if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { - - /* finish completing original command */ - spin_lock_irqsave(&host_set->lock, flags); - __ata_qc_complete(qc); - spin_unlock_irqrestore(&host_set->lock, flags); - - atapi_request_sense(ap, dev, cmd); - - cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); - scsi_finish_command(cmd); - - goto out; - } - } + ap->hsm_task_state = HSM_ST_IDLE; spin_lock_irqsave(&host_set->lock, flags); - /* hack alert! We cannot use the supplied completion - * function from inside the ->eh_strategy_handler() thread. - * libata is the only user of ->eh_strategy_handler() in - * any kernel, so the default scsi_done() assumes it is - * not being called from the SCSI EH. - */ - qc->scsidone = scsi_finish_command; - switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -3055,13 +3835,14 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) ap->id, qc->tf.command, drv_stat, host_stat); /* complete taskfile transaction */ - ata_qc_complete(qc, drv_stat); + qc->err_mask |= ac_err_mask(drv_stat); break; } spin_unlock_irqrestore(&host_set->lock, flags); -out: + ata_eh_qc_complete(qc); + DPRINTK("EXIT\n"); } @@ -3086,20 +3867,10 @@ out: void ata_eng_timeout(struct ata_port *ap) { - struct ata_queued_cmd *qc; - DPRINTK("ENTER\n"); - qc = ata_qc_from_tag(ap, ap->active_tag); - if (!qc) { - printk(KERN_ERR "ata%u: BUG: timeout without command\n", - ap->id); - goto out; - } - - ata_qc_timeout(qc); + ata_qc_timeout(ata_qc_from_tag(ap, ap->active_tag)); -out: DPRINTK("EXIT\n"); } @@ -3145,53 +3916,16 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, qc = ata_qc_new(ap); if (qc) { - qc->sg = NULL; - qc->flags = 0; qc->scsicmd = NULL; qc->ap = ap; qc->dev = dev; - qc->cursect = qc->cursg = qc->cursg_ofs = 0; - qc->nsect = 0; - qc->nbytes = qc->curbytes = 0; - ata_tf_init(ap, &qc->tf, dev->devno); - - if (dev->flags & ATA_DFLAG_LBA48) - qc->tf.flags |= ATA_TFLAG_LBA48; + ata_qc_reinit(qc); } return qc; } -static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) -{ - return 0; -} - -static void __ata_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int tag, do_clear = 0; - - qc->flags = 0; - tag = qc->tag; - if (likely(ata_tag_valid(tag))) { - if (tag == ap->active_tag) - ap->active_tag = ATA_TAG_POISON; - qc->tag = ATA_TAG_POISON; - do_clear = 1; - } - - if (qc->waiting) { - struct completion *waiting = qc->waiting; - qc->waiting = NULL; - complete(waiting); - } - - if (likely(do_clear)) - clear_bit(tag, &ap->qactive); -} - /** * ata_qc_free - free unused ata_queued_cmd * @qc: Command to complete @@ -3201,35 +3935,28 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc) * * LOCKING: * spin_lock_irqsave(host_set lock) - * */ void ata_qc_free(struct ata_queued_cmd *qc) { - assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ - assert(qc->waiting == NULL); /* nothing should be waiting */ + struct ata_port *ap = qc->ap; + unsigned int tag; - __ata_qc_complete(qc); -} + WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ -/** - * ata_qc_complete - Complete an active ATA command - * @qc: Command to complete - * @drv_stat: ATA Status register contents - * - * Indicate to the mid and upper layers that an ATA - * command has completed, with either an ok or not-ok status. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - * - */ + qc->flags = 0; + tag = qc->tag; + if (likely(ata_tag_valid(tag))) { + if (tag == ap->active_tag) + ap->active_tag = ATA_TAG_POISON; + qc->tag = ATA_TAG_POISON; + clear_bit(tag, &ap->qactive); + } +} -void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) +void __ata_qc_complete(struct ata_queued_cmd *qc) { - int rc; - - assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ - assert(qc->flags & ATA_QCFLAG_ACTIVE); + WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ + WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) ata_sg_clean(qc); @@ -3241,17 +3968,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ - rc = qc->complete_fn(qc, drv_stat); - - /* if callback indicates not to complete command (non-zero), - * return immediately - */ - if (rc != 0) - return; - - __ata_qc_complete(qc); - - VPRINTK("EXIT\n"); + qc->complete_fn(qc); } static inline int ata_should_dma_map(struct ata_queued_cmd *qc) @@ -3265,7 +3982,6 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) case ATA_PROT_ATAPI: case ATA_PROT_PIO: - case ATA_PROT_PIO_MULT: if (ap->flags & ATA_FLAG_PIO_DMA) return 1; @@ -3289,22 +4005,21 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) * * LOCKING: * spin_lock_irqsave(host_set lock) - * - * RETURNS: - * Zero on success, negative on error. */ - -int ata_qc_issue(struct ata_queued_cmd *qc) +void ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; + qc->ap->active_tag = qc->tag; + qc->flags |= ATA_QCFLAG_ACTIVE; + if (ata_should_dma_map(qc)) { if (qc->flags & ATA_QCFLAG_SG) { if (ata_sg_setup(qc)) - goto err_out; + goto sg_err; } else if (qc->flags & ATA_QCFLAG_SINGLE) { if (ata_sg_setup_one(qc)) - goto err_out; + goto sg_err; } } else { qc->flags &= ~ATA_QCFLAG_DMAMAP; @@ -3312,16 +4027,18 @@ int ata_qc_issue(struct ata_queued_cmd *qc) ap->ops->qc_prep(qc); - qc->ap->active_tag = qc->tag; - qc->flags |= ATA_QCFLAG_ACTIVE; - - return ap->ops->qc_issue(qc); + qc->err_mask |= ap->ops->qc_issue(qc); + if (unlikely(qc->err_mask)) + goto err; + return; -err_out: - return -1; +sg_err: + qc->flags &= ~ATA_QCFLAG_DMAMAP; + qc->err_mask |= AC_ERR_SYSTEM; +err: + ata_qc_complete(qc); } - /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device @@ -3337,10 +4054,10 @@ err_out: * spin_lock_irqsave(host_set lock) * * RETURNS: - * Zero on success, negative on error. + * Zero on success, AC_ERR_* mask on failure */ -int ata_qc_issue_prot(struct ata_queued_cmd *qc) +unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; @@ -3348,278 +4065,47 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) switch (qc->tf.protocol) { case ATA_PROT_NODATA: - ata_tf_to_host_nolock(ap, &qc->tf); + ata_tf_to_host(ap, &qc->tf); break; case ATA_PROT_DMA: ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ ap->ops->bmdma_setup(qc); /* set up bmdma */ - ap->ops->bmdma_start(qc); /* initiate bmdma */ - break; - - case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ - ata_qc_set_polling(qc); - ata_tf_to_host_nolock(ap, &qc->tf); - ap->pio_task_state = PIO_ST; - queue_work(ata_wq, &ap->pio_task); - break; - - case ATA_PROT_ATAPI: - ata_qc_set_polling(qc); - ata_tf_to_host_nolock(ap, &qc->tf); - queue_work(ata_wq, &ap->packet_task); - break; - - case ATA_PROT_ATAPI_NODATA: - ap->flags |= ATA_FLAG_NOINTR; - ata_tf_to_host_nolock(ap, &qc->tf); - queue_work(ata_wq, &ap->packet_task); - break; - - case ATA_PROT_ATAPI_DMA: - ap->flags |= ATA_FLAG_NOINTR; - ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ - ap->ops->bmdma_setup(qc); /* set up bmdma */ - queue_work(ata_wq, &ap->packet_task); - break; - - default: - WARN_ON(1); - return -1; - } - - return 0; -} - -/** - * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 dmactl; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - - /* load PRD table addr. */ - mb(); /* make sure PRD table writes are visible to controller */ - writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS); - - /* specify data direction, triple-check start bit is clear */ - dmactl = readb(mmio + ATA_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - writeb(dmactl, mmio + ATA_DMA_CMD); - - /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); -} - -/** - * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - u8 dmactl; - - /* start host DMA transaction */ - dmactl = readb(mmio + ATA_DMA_CMD); - writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); - - /* Strictly, one may wish to issue a readb() here, to - * flush the mmio write. However, control also passes - * to the hardware at this point, and it will interrupt - * us when we are to resume control. So, in effect, - * we don't care when the mmio write flushes. - * Further, a read of the DMA status register _immediately_ - * following the write may not be what certain flaky hardware - * is expected, so I think it is best to not add a readb() - * without first all the MMIO ATA cards/mobos. - * Or maybe I'm just being paranoid. - */ -} - -/** - * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO) - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE); - u8 dmactl; - - /* load PRD table addr. */ - outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS); - - /* specify data direction, triple-check start bit is clear */ - dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - dmactl &= ~(ATA_DMA_WR | ATA_DMA_START); - if (!rw) - dmactl |= ATA_DMA_WR; - outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - - /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); -} - -/** - * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO) - * @qc: Info associated with this ATA transaction. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - u8 dmactl; - - /* start host DMA transaction */ - dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); - outb(dmactl | ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); -} - - -/** - * ata_bmdma_start - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes the ATA_DMA_START flag to the DMA command register. - * - * May be used as the bmdma_start() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_bmdma_start(struct ata_queued_cmd *qc) -{ - if (qc->ap->flags & ATA_FLAG_MMIO) - ata_bmdma_start_mmio(qc); - else - ata_bmdma_start_pio(qc); -} - - -/** - * ata_bmdma_setup - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes address of PRD table to device's PRD Table Address - * register, sets the DMA control register, and calls - * ops->exec_command() to start the transfer. - * - * May be used as the bmdma_setup() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -void ata_bmdma_setup(struct ata_queued_cmd *qc) -{ - if (qc->ap->flags & ATA_FLAG_MMIO) - ata_bmdma_setup_mmio(qc); - else - ata_bmdma_setup_pio(qc); -} - - -/** - * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. - * @ap: Port associated with this ATA transaction. - * - * Clear interrupt and error flags in DMA status register. - * - * May be used as the irq_clear() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -void ata_bmdma_irq_clear(struct ata_port *ap) -{ - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS; - writeb(readb(mmio), mmio); - } else { - unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS; - outb(inb(addr), addr); - } - -} - - -/** - * ata_bmdma_status - Read PCI IDE BMDMA status - * @ap: Port associated with this ATA transaction. - * - * Read and return BMDMA status register. - * - * May be used as the bmdma_status() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - -u8 ata_bmdma_status(struct ata_port *ap) -{ - u8 host_stat; - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; - host_stat = readb(mmio + ATA_DMA_STATUS); - } else - host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); - return host_stat; -} + ap->ops->bmdma_start(qc); /* initiate bmdma */ + break; + case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ + ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); + ap->hsm_task_state = HSM_ST; + ata_port_queue_task(ap, ata_pio_task, ap, 0); + break; -/** - * ata_bmdma_stop - Stop PCI IDE BMDMA transfer - * @qc: Command we are ending DMA for - * - * Clears the ATA_DMA_START flag in the dma control register - * - * May be used as the bmdma_stop() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ + case ATA_PROT_ATAPI: + ata_qc_set_polling(qc); + ata_tf_to_host(ap, &qc->tf); + ata_port_queue_task(ap, atapi_packet_task, ap, 0); + break; -void ata_bmdma_stop(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - if (ap->flags & ATA_FLAG_MMIO) { - void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; + case ATA_PROT_ATAPI_NODATA: + ap->flags |= ATA_FLAG_NOINTR; + ata_tf_to_host(ap, &qc->tf); + ata_port_queue_task(ap, atapi_packet_task, ap, 0); + break; - /* clear start/stop bit */ - writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START, - mmio + ATA_DMA_CMD); - } else { - /* clear start/stop bit */ - outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START, - ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + case ATA_PROT_ATAPI_DMA: + ap->flags |= ATA_FLAG_NOINTR; + ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ + ap->ops->bmdma_setup(qc); /* set up bmdma */ + ata_port_queue_task(ap, atapi_packet_task, ap, 0); + break; + + default: + WARN_ON(1); + return AC_ERR_SYSTEM; } - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ + return 0; } /** @@ -3679,7 +4165,8 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ap->ops->irq_clear(ap); /* complete taskfile transaction */ - ata_qc_complete(qc, status); + qc->err_mask |= ac_err_mask(status); + ata_qc_complete(qc); break; default: @@ -3693,9 +4180,9 @@ idle_irq: #ifdef ATA_IRQ_TRAP if ((ap->stats.idle_irq % 1000) == 0) { - handled = 1; ata_irq_ack(ap, 0); /* debug trap */ printk(KERN_WARNING "ata%d: irq trap\n", ap->id); + return 1; } #endif return 0; /* irq not handled */ @@ -3715,7 +4202,6 @@ idle_irq: * * RETURNS: * IRQ_NONE or IRQ_HANDLED. - * */ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) @@ -3748,74 +4234,102 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) return IRQ_RETVAL(handled); } -/** - * atapi_packet_task - Write CDB bytes to hardware - * @_data: Port to which ATAPI device is attached. - * - * When device has indicated its readiness to accept - * a CDB, this function is called. Send the CDB. - * If DMA is to be performed, exit immediately. - * Otherwise, we are in polling mode, so poll - * status under operation succeeds or fails. - * - * LOCKING: - * Kernel thread context (may sleep) - */ -static void atapi_packet_task(void *_data) +/* + * Execute a 'simple' command, that only consists of the opcode 'cmd' itself, + * without filling any other registers + */ +static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev, + u8 cmd) { - struct ata_port *ap = _data; - struct ata_queued_cmd *qc; - u8 status; + struct ata_taskfile tf; + int err; - qc = ata_qc_from_tag(ap, ap->active_tag); - assert(qc != NULL); - assert(qc->flags & ATA_QCFLAG_ACTIVE); + ata_tf_init(ap, &tf, dev->devno); - /* sleep-wait for BSY to clear */ - DPRINTK("busy wait\n"); - if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) - goto err_out; + tf.command = cmd; + tf.flags |= ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_NODATA; - /* make sure DRQ is set */ - status = ata_chk_status(ap); - if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) - goto err_out; + err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0); + if (err) + printk(KERN_ERR "%s: ata command failed: %d\n", + __FUNCTION__, err); - /* send SCSI cdb */ - DPRINTK("send cdb\n"); - assert(ap->cdb_len >= 12); + return err; +} - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || - qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { - unsigned long flags; +static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev) +{ + u8 cmd; - /* Once we're done issuing command and kicking bmdma, - * irq handler takes over. To not lose irq, we need - * to clear NOINTR flag before sending cdb, but - * interrupt handler shouldn't be invoked before we're - * finished. Hence, the following locking. - */ - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->flags &= ~ATA_FLAG_NOINTR; - ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); - if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) - ap->ops->bmdma_start(qc); /* initiate bmdma */ - spin_unlock_irqrestore(&ap->host_set->lock, flags); - } else { - ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); + if (!ata_try_flush_cache(dev)) + return 0; - /* PIO commands are handled by polling */ - ap->pio_task_state = PIO_ST; - queue_work(ata_wq, &ap->pio_task); - } + if (ata_id_has_flush_ext(dev->id)) + cmd = ATA_CMD_FLUSH_EXT; + else + cmd = ATA_CMD_FLUSH; - return; + return ata_do_simple_cmd(ap, dev, cmd); +} -err_out: - ata_poll_qc_complete(qc, ATA_ERR); +static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev) +{ + return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1); +} + +static int ata_start_drive(struct ata_port *ap, struct ata_device *dev) +{ + return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE); +} + +/** + * ata_device_resume - wakeup a previously suspended devices + * @ap: port the device is connected to + * @dev: the device to resume + * + * Kick the drive back into action, by sending it an idle immediate + * command and making sure its transfer mode matches between drive + * and host. + * + */ +int ata_device_resume(struct ata_port *ap, struct ata_device *dev) +{ + if (ap->flags & ATA_FLAG_SUSPENDED) { + ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000); + ap->flags &= ~ATA_FLAG_SUSPENDED; + ata_set_mode(ap); + } + if (!ata_dev_present(dev)) + return 0; + if (dev->class == ATA_DEV_ATA) + ata_start_drive(ap, dev); + + return 0; } +/** + * ata_device_suspend - prepare a device for suspend + * @ap: port the device is connected to + * @dev: the device to suspend + * @state: target power management state + * + * Flush the cache on the drive, if appropriate, then issue a + * standbynow command. + */ +int ata_device_suspend(struct ata_port *ap, struct ata_device *dev, pm_message_t state) +{ + if (!ata_dev_present(dev)) + return 0; + if (dev->class == ATA_DEV_ATA) + ata_flush_cache(ap, dev); + + if (state.event != PM_EVENT_FREEZE) + ata_standby_drive(ap, dev); + ap->flags |= ATA_FLAG_SUSPENDED; + return 0; +} /** * ata_port_start - Set port up for dma. @@ -3827,16 +4341,24 @@ err_out: * May be used as the port_start() entry in ata_port_operations. * * LOCKING: + * Inherited from caller. */ int ata_port_start (struct ata_port *ap) { - struct device *dev = ap->host_set->dev; + struct device *dev = ap->dev; + int rc; ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); if (!ap->prd) return -ENOMEM; + rc = ata_pad_alloc(ap, dev); + if (rc) { + dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); + return rc; + } + DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); return 0; @@ -3852,13 +4374,15 @@ int ata_port_start (struct ata_port *ap) * May be used as the port_stop() entry in ata_port_operations. * * LOCKING: + * Inherited from caller. */ void ata_port_stop (struct ata_port *ap) { - struct device *dev = ap->host_set->dev; + struct device *dev = ap->dev; dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); + ata_pad_free(ap, dev); } void ata_host_stop (struct ata_host_set *host_set) @@ -3874,6 +4398,7 @@ void ata_host_stop (struct ata_host_set *host_set) * @do_unregister: 1 if we fully unregister, 0 to just stop the port * * LOCKING: + * Inherited from caller. */ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) @@ -3901,12 +4426,11 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) * * LOCKING: * Inherited from caller. - * */ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, struct ata_host_set *host_set, - struct ata_probe_ent *ent, unsigned int port_no) + const struct ata_probe_ent *ent, unsigned int port_no) { unsigned int i; @@ -3916,13 +4440,12 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, host->unique_id = ata_unique_id++; host->max_cmd_len = 12; - scsi_assign_lock(host, &host_set->lock); - ap->flags = ATA_FLAG_PORT_DISABLED; ap->id = host->unique_id; ap->host = host; ap->ctl = ATA_DEVCTL_OBS; ap->host_set = host_set; + ap->dev = ent->dev; ap->port_no = port_no; ap->hard_port_no = ent->legacy_mode ? ent->hard_port_no : port_no; @@ -3935,11 +4458,16 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ap->active_tag = ATA_TAG_POISON; ap->last_ctl = 0xFF; - INIT_WORK(&ap->packet_task, atapi_packet_task, ap); - INIT_WORK(&ap->pio_task, ata_pio_task, ap); + INIT_WORK(&ap->port_task, NULL, NULL); + INIT_LIST_HEAD(&ap->eh_done_q); - for (i = 0; i < ATA_MAX_DEVICES; i++) - ap->device[i].devno = i; + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + dev->devno = i; + dev->pio_mask = UINT_MAX; + dev->mwdma_mask = UINT_MAX; + dev->udma_mask = UINT_MAX; + } #ifdef ATA_IRQ_TRAP ap->stats.unhandled_irq = 1; @@ -3962,10 +4490,9 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, * * RETURNS: * New ata_port on success, for NULL on error. - * */ -static struct ata_port * ata_host_add(struct ata_probe_ent *ent, +static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, struct ata_host_set *host_set, unsigned int port_no) { @@ -3974,10 +4501,20 @@ static struct ata_port * ata_host_add(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; + host->transportt = &ata_scsi_transport_template; + ap = (struct ata_port *) &host->hostdata[0]; ata_host_init(ap, host, host_set, ent, port_no); @@ -4010,10 +4547,9 @@ err_out: * * RETURNS: * Number of ports registered. Zero on error (no ports registered). - * */ -int ata_device_add(struct ata_probe_ent *ent) +int ata_device_add(const struct ata_probe_ent *ent) { unsigned int count = 0, i; struct device *dev = ent->dev; @@ -4021,11 +4557,10 @@ int ata_device_add(struct ata_probe_ent *ent) DPRINTK("ENTER\n"); /* alloc a container for our list of ATA ports (buses) */ - host_set = kmalloc(sizeof(struct ata_host_set) + + host_set = kzalloc(sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)), GFP_KERNEL); if (!host_set) return 0; - memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *))); spin_lock_init(&host_set->lock); host_set->dev = dev; @@ -4034,6 +4569,7 @@ int ata_device_add(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++) { @@ -4065,10 +4601,8 @@ int ata_device_add(struct ata_probe_ent *ent) count++; } - if (!count) { - kfree(host_set); - return 0; - } + if (!count) + goto err_free_ret; /* obtain irq, that is shared between channels */ if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, @@ -4083,9 +4617,9 @@ int ata_device_add(struct ata_probe_ent *ent) ap = host_set->ports[i]; - DPRINTK("ata%u: probe begin\n", ap->id); + DPRINTK("ata%u: bus probe begin\n", ap->id); rc = ata_bus_probe(ap); - DPRINTK("ata%u: probe end\n", ap->id); + DPRINTK("ata%u: bus probe end\n", ap->id); if (rc) { /* FIXME: do something useful here? @@ -4109,7 +4643,7 @@ int ata_device_add(struct ata_probe_ent *ent) } /* probes are done, now scan each port's disk(s) */ - DPRINTK("probe begin\n"); + DPRINTK("host probe begin\n"); for (i = 0; i < count; i++) { struct ata_port *ap = host_set->ports[i]; @@ -4126,6 +4660,7 @@ err_out: ata_host_remove(host_set->ports[i], 1); scsi_host_put(host_set->ports[i]->host); } +err_free_ret: kfree(host_set); VPRINTK("EXIT, returning 0\n"); return 0; @@ -4135,14 +4670,13 @@ err_out: * ata_host_set_remove - PCI layer callback for device removal * @host_set: ATA host set that was removed * - * Unregister all objects associated with this host set. Free those + * Unregister all objects associated with this host set. Free those * objects. * * LOCKING: * Inherited from calling layer (may sleep). */ - void ata_host_set_remove(struct ata_host_set *host_set) { struct ata_port *ap; @@ -4195,11 +4729,14 @@ void ata_host_set_remove(struct ata_host_set *host_set) int ata_scsi_release(struct Scsi_Host *host) { struct ata_port *ap = (struct ata_port *) &host->hostdata[0]; + int i; DPRINTK("ENTER\n"); ap->ops->port_disable(ap); ata_host_remove(ap, 0); + for (i = 0; i < ATA_MAX_DEVICES; i++) + kfree(ap->device[i].id); DPRINTK("EXIT\n"); return 1; @@ -4231,34 +4768,6 @@ void ata_std_ports(struct ata_ioports *ioaddr) ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; } -static struct ata_probe_ent * -ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port) -{ - struct ata_probe_ent *probe_ent; - - probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) { - printk(KERN_ERR DRV_NAME "(%s): out of memory\n", - kobject_name(&(dev->kobj))); - return NULL; - } - - memset(probe_ent, 0, sizeof(*probe_ent)); - - INIT_LIST_HEAD(&probe_ent->node); - probe_ent->dev = dev; - - probe_ent->sht = port->sht; - probe_ent->host_flags = port->host_flags; - probe_ent->pio_mask = port->pio_mask; - probe_ent->mwdma_mask = port->mwdma_mask; - probe_ent->udma_mask = port->udma_mask; - probe_ent->port_ops = port->port_ops; - - return probe_ent; -} - - #ifdef CONFIG_PCI @@ -4270,242 +4779,11 @@ void ata_pci_host_stop (struct ata_host_set *host_set) } /** - * ata_pci_init_native_mode - Initialize native-mode driver - * @pdev: pci device to be initialized - * @port: array[2] of pointers to port info structures. - * - * Utility function which allocates and initializes an - * ata_probe_ent structure for a standard dual-port - * PIO-based IDE controller. The returned ata_probe_ent - * structure can be passed to ata_device_add(). The returned - * ata_probe_ent structure should then be freed with kfree(). - */ - -struct ata_probe_ent * -ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) -{ - struct ata_probe_ent *probe_ent = - ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); - if (!probe_ent) - return NULL; - - probe_ent->n_ports = 2; - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = SA_SHIRQ; - - probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0); - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = - pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; - probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4); - - probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2); - probe_ent->port[1].altstatus_addr = - probe_ent->port[1].ctl_addr = - pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; - probe_ent->port[1].bmdma_addr = pci_resource_start(pdev, 4) + 8; - - ata_std_ports(&probe_ent->port[0]); - ata_std_ports(&probe_ent->port[1]); - - return probe_ent; -} - -static struct ata_probe_ent * -ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, - struct ata_probe_ent **ppe2) -{ - struct ata_probe_ent *probe_ent, *probe_ent2; - - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); - if (!probe_ent) - return NULL; - probe_ent2 = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[1]); - if (!probe_ent2) { - kfree(probe_ent); - return NULL; - } - - probe_ent->n_ports = 1; - probe_ent->irq = 14; - - probe_ent->hard_port_no = 0; - probe_ent->legacy_mode = 1; - - probe_ent2->n_ports = 1; - probe_ent2->irq = 15; - - probe_ent2->hard_port_no = 1; - probe_ent2->legacy_mode = 1; - - probe_ent->port[0].cmd_addr = 0x1f0; - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = 0x3f6; - probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4); - - probe_ent2->port[0].cmd_addr = 0x170; - probe_ent2->port[0].altstatus_addr = - probe_ent2->port[0].ctl_addr = 0x376; - probe_ent2->port[0].bmdma_addr = pci_resource_start(pdev, 4)+8; - - ata_std_ports(&probe_ent->port[0]); - ata_std_ports(&probe_ent2->port[0]); - - *ppe2 = probe_ent2; - return probe_ent; -} - -/** - * ata_pci_init_one - Initialize/register PCI IDE host controller - * @pdev: Controller to be initialized - * @port_info: Information from low-level host driver - * @n_ports: Number of ports attached to host controller - * - * This is a helper function which can be called from a driver's - * xxx_init_one() probe function if the hardware uses traditional - * IDE taskfile registers. - * - * This function calls pci_enable_device(), reserves its register - * regions, sets the dma mask, enables bus master mode, and calls - * ata_device_add() - * - * LOCKING: - * Inherited from PCI layer (may sleep). - * - * RETURNS: - * Zero on success, negative on errno-based value on error. - * - */ - -int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, - unsigned int n_ports) -{ - struct ata_probe_ent *probe_ent, *probe_ent2 = NULL; - struct ata_port_info *port[2]; - u8 tmp8, mask; - unsigned int legacy_mode = 0; - int disable_dev_on_err = 1; - int rc; - - DPRINTK("ENTER\n"); - - port[0] = port_info[0]; - if (n_ports > 1) - port[1] = port_info[1]; - else - port[1] = port[0]; - - if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 - && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - /* TODO: support transitioning to native mode? */ - pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); - mask = (1 << 2) | (1 << 0); - if ((tmp8 & mask) != mask) - legacy_mode = (1 << 3); - } - - /* FIXME... */ - if ((!legacy_mode) && (n_ports > 1)) { - printk(KERN_ERR "ata: BUG: native mode, n_ports > 1\n"); - return -EINVAL; - } - - rc = pci_enable_device(pdev); - if (rc) - return rc; - - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) { - disable_dev_on_err = 0; - goto err_out; - } - - if (legacy_mode) { - if (!request_region(0x1f0, 8, "libata")) { - struct resource *conflict, res; - res.start = 0x1f0; - res.end = 0x1f0 + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= (1 << 0); - else { - disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); - } - } else - legacy_mode |= (1 << 0); - - if (!request_region(0x170, 8, "libata")) { - struct resource *conflict, res; - res.start = 0x170; - res.end = 0x170 + 8 - 1; - conflict = ____request_resource(&ioport_resource, &res); - if (!strcmp(conflict->name, "libata")) - legacy_mode |= (1 << 1); - else { - disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); - } - } else - legacy_mode |= (1 << 1); - } - - /* we have legacy mode, but all ports are unavailable */ - if (legacy_mode == (1 << 3)) { - rc = -EBUSY; - goto err_out_regions; - } - - rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - goto err_out_regions; - rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); - if (rc) - goto err_out_regions; - - if (legacy_mode) { - probe_ent = ata_pci_init_legacy_mode(pdev, port, &probe_ent2); - } else - probe_ent = ata_pci_init_native_mode(pdev, port); - if (!probe_ent) { - rc = -ENOMEM; - goto err_out_regions; - } - - pci_set_master(pdev); - - /* FIXME: check ata_device_add return */ - if (legacy_mode) { - if (legacy_mode & (1 << 0)) - ata_device_add(probe_ent); - if (legacy_mode & (1 << 1)) - ata_device_add(probe_ent2); - } else - ata_device_add(probe_ent); - - kfree(probe_ent); - kfree(probe_ent2); - - return 0; - -err_out_regions: - if (legacy_mode & (1 << 0)) - release_region(0x1f0, 8); - if (legacy_mode & (1 << 1)) - release_region(0x170, 8); - pci_release_regions(pdev); -err_out: - if (disable_dev_on_err) - pci_disable_device(pdev); - return rc; -} - -/** * ata_pci_remove_one - PCI layer callback for device removal * @pdev: PCI device that was removed * * PCI layer indicates to libata via this hook that - * hot-unplug or module unload event has occured. + * hot-unplug or module unload event has occurred. * Handle this by unregistering all objects associated * with this PCI device. Free those objects. Then finally * release PCI resources and disable device. @@ -4526,7 +4804,7 @@ void ata_pci_remove_one (struct pci_dev *pdev) } /* move to PCI subsystem */ -int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits) +int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) { unsigned long tmp = 0; @@ -4558,6 +4836,23 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits) return (tmp == bits->val) ? 1 : 0; } + +int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state) +{ + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + return 0; +} + +int ata_pci_device_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_enable_device(pdev); + pci_set_master(pdev); + return 0; +} #endif /* CONFIG_PCI */ @@ -4579,6 +4874,27 @@ static void __exit ata_exit(void) module_init(ata_init); module_exit(ata_exit); +static unsigned long ratelimit_time; +static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED; + +int ata_ratelimit(void) +{ + int rc; + unsigned long flags; + + spin_lock_irqsave(&ata_ratelimit_lock, flags); + + if (time_after(jiffies, ratelimit_time)) { + rc = 1; + ratelimit_time = jiffies + (HZ/5); + } else + rc = 0; + + spin_unlock_irqrestore(&ata_ratelimit_lock, flags); + + return rc; +} + /* * libata is essentially a library of internal helper functions for * low-level ATA host controller drivers. As such, the API/ABI is @@ -4592,7 +4908,7 @@ EXPORT_SYMBOL_GPL(ata_device_add); EXPORT_SYMBOL_GPL(ata_host_set_remove); EXPORT_SYMBOL_GPL(ata_sg_init); EXPORT_SYMBOL_GPL(ata_sg_init_one); -EXPORT_SYMBOL_GPL(ata_qc_complete); +EXPORT_SYMBOL_GPL(__ata_qc_complete); EXPORT_SYMBOL_GPL(ata_qc_issue_prot); EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_tf_load); @@ -4603,13 +4919,13 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis); EXPORT_SYMBOL_GPL(ata_tf_from_fis); EXPORT_SYMBOL_GPL(ata_check_status); EXPORT_SYMBOL_GPL(ata_altstatus); -EXPORT_SYMBOL_GPL(ata_chk_err); EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); EXPORT_SYMBOL_GPL(ata_host_stop); EXPORT_SYMBOL_GPL(ata_interrupt); EXPORT_SYMBOL_GPL(ata_qc_prep); +EXPORT_SYMBOL_GPL(ata_noop_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); EXPORT_SYMBOL_GPL(ata_bmdma_start); EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear); @@ -4619,17 +4935,33 @@ EXPORT_SYMBOL_GPL(ata_port_probe); EXPORT_SYMBOL_GPL(sata_phy_reset); EXPORT_SYMBOL_GPL(__sata_phy_reset); EXPORT_SYMBOL_GPL(ata_bus_reset); +EXPORT_SYMBOL_GPL(ata_std_probeinit); +EXPORT_SYMBOL_GPL(ata_std_softreset); +EXPORT_SYMBOL_GPL(sata_std_hardreset); +EXPORT_SYMBOL_GPL(ata_std_postreset); +EXPORT_SYMBOL_GPL(ata_std_probe_reset); +EXPORT_SYMBOL_GPL(ata_drive_probe_reset); +EXPORT_SYMBOL_GPL(ata_dev_revalidate); +EXPORT_SYMBOL_GPL(ata_dev_classify); +EXPORT_SYMBOL_GPL(ata_dev_pair); EXPORT_SYMBOL_GPL(ata_port_disable); +EXPORT_SYMBOL_GPL(ata_ratelimit); +EXPORT_SYMBOL_GPL(ata_busy_sleep); +EXPORT_SYMBOL_GPL(ata_port_queue_task); EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); -EXPORT_SYMBOL_GPL(ata_scsi_error); EXPORT_SYMBOL_GPL(ata_scsi_slave_config); EXPORT_SYMBOL_GPL(ata_scsi_release); EXPORT_SYMBOL_GPL(ata_host_intr); -EXPORT_SYMBOL_GPL(ata_dev_classify); -EXPORT_SYMBOL_GPL(ata_dev_id_string); -EXPORT_SYMBOL_GPL(ata_dev_config); +EXPORT_SYMBOL_GPL(ata_id_string); +EXPORT_SYMBOL_GPL(ata_id_c_string); EXPORT_SYMBOL_GPL(ata_scsi_simulate); +EXPORT_SYMBOL_GPL(ata_eh_qc_complete); +EXPORT_SYMBOL_GPL(ata_eh_qc_retry); + +EXPORT_SYMBOL_GPL(ata_pio_need_iordy); +EXPORT_SYMBOL_GPL(ata_timing_compute); +EXPORT_SYMBOL_GPL(ata_timing_merge); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); @@ -4637,4 +4969,13 @@ EXPORT_SYMBOL_GPL(ata_pci_host_stop); EXPORT_SYMBOL_GPL(ata_pci_init_native_mode); EXPORT_SYMBOL_GPL(ata_pci_init_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); +EXPORT_SYMBOL_GPL(ata_pci_device_suspend); +EXPORT_SYMBOL_GPL(ata_pci_device_resume); +EXPORT_SYMBOL_GPL(ata_pci_default_filter); +EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ + +EXPORT_SYMBOL_GPL(ata_device_suspend); +EXPORT_SYMBOL_GPL(ata_device_resume); +EXPORT_SYMBOL_GPL(ata_scsi_device_suspend); +EXPORT_SYMBOL_GPL(ata_scsi_device_resume);