diff --git a/[refs] b/[refs] index 1b203b4c8d6c..b5c698a41713 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 054ee8fd39f1b5d50e803f126b63f400d631eea4 +refs/heads/master: 08db2a701bd63d0e36f06a29137bf016a907cf71 diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index bbd9c2323d8c..5627ce1d2b32 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -356,7 +356,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int /* * PIIX4 ACPI: Two IO regions pointed to by longwords at * 0x40 (64 bytes of ACPI registers) - * 0x90 (32 bytes of SMB registers) + * 0x90 (16 bytes of SMB registers) * and a few strange programmable PIIX4 device resources. */ static void __devinit quirk_piix4_acpi(struct pci_dev *dev) @@ -366,7 +366,7 @@ static void __devinit quirk_piix4_acpi(struct pci_dev *dev) pci_read_config_dword(dev, 0x40, ®ion); quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); pci_read_config_dword(dev, 0x90, ®ion); - quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); + quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); /* Device resource A has enables for some of the other ones */ pci_read_config_dword(dev, 0x5c, &res_a); diff --git a/trunk/drivers/scsi/ahci.c b/trunk/drivers/scsi/ahci.c index 25a47d7afa28..fe8187d6f58b 100644 --- a/trunk/drivers/scsi/ahci.c +++ b/trunk/drivers/scsi/ahci.c @@ -192,6 +192,7 @@ static void ahci_port_stop(struct ata_port *ap); static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void ahci_qc_prep(struct ata_queued_cmd *qc); static u8 ahci_check_status(struct ata_port *ap); +static u8 ahci_check_err(struct ata_port *ap); static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); static void ahci_remove_one (struct pci_dev *pdev); @@ -220,6 +221,7 @@ static const struct ata_port_operations ahci_ops = { .check_status = ahci_check_status, .check_altstatus = ahci_check_status, + .check_err = ahci_check_err, .dev_select = ata_noop_dev_select, .tf_read = ahci_tf_read, @@ -312,15 +314,8 @@ static int ahci_port_start(struct ata_port *ap) return -ENOMEM; memset(pp, 0, sizeof(*pp)); - ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); - if (!ap->pad) { - kfree(pp); - return -ENOMEM; - } - mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); return -ENOMEM; } @@ -396,7 +391,6 @@ static void ahci_port_stop(struct ata_port *ap) ap->private_data = NULL; dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); - dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); kfree(pp); } @@ -464,6 +458,13 @@ static u8 ahci_check_status(struct ata_port *ap) return readl(mmio + PORT_TFDATA) & 0xFF; } +static u8 ahci_check_err(struct ata_port *ap) +{ + void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; + + return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF; +} + static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ahci_port_priv *pp = ap->private_data; @@ -475,23 +476,23 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) static void ahci_fill_sg(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; - struct scatterlist *sg; - struct ahci_sg *ahci_sg; + unsigned int i; VPRINTK("ENTER\n"); /* * Next, the S/G list. */ - ahci_sg = pp->cmd_tbl_sg; - ata_for_each_sg(sg, qc) { - dma_addr_t addr = sg_dma_address(sg); - u32 sg_len = sg_dma_len(sg); - - ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); - ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); - ahci_sg->flags_size = cpu_to_le32(sg_len - 1); - ahci_sg++; + for (i = 0; i < qc->n_elem; i++) { + u32 sg_len; + dma_addr_t addr; + + addr = sg_dma_address(&qc->sg[i]); + sg_len = sg_dma_len(&qc->sg[i]); + + pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff); + pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); + pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1); } } @@ -608,7 +609,7 @@ static void ahci_eng_timeout(struct ata_port *ap) * not being called from the SCSI EH. */ qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + ata_qc_complete(qc, ATA_ERR); } spin_unlock_irqrestore(&host_set->lock, flags); @@ -637,7 +638,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (status & PORT_IRQ_FATAL) { ahci_intr_error(ap, status); if (qc) - ata_qc_complete(qc, AC_ERR_OTHER); + ata_qc_complete(qc, ATA_ERR); } return 1; diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index 6cab14965cc8..5ca97605ff35 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -372,7 +372,7 @@ static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) struct ata_ioports *ioaddr = &ap->ioaddr; tf->command = ata_check_status(ap); - tf->feature = inb(ioaddr->error_addr); + tf->feature = ata_chk_err(ap); tf->nsect = inb(ioaddr->nsect_addr); tf->lbal = inb(ioaddr->lbal_addr); tf->lbam = inb(ioaddr->lbam_addr); @@ -406,7 +406,7 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) struct ata_ioports *ioaddr = &ap->ioaddr; tf->command = ata_check_status(ap); - tf->feature = readb((void __iomem *)ioaddr->error_addr); + tf->feature = ata_chk_err(ap); tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); @@ -526,6 +526,30 @@ u8 ata_altstatus(struct ata_port *ap) } +/** + * 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. + * + * Note: may NOT be used as the check_err() entry in + * ata_port_operations. + * + * LOCKING: + * Inherited from caller. + */ +u8 ata_chk_err(struct ata_port *ap) +{ + if (ap->ops->check_err) + return ap->ops->check_err(ap); + + if (ap->flags & ATA_FLAG_MMIO) { + return readb((void __iomem *) ap->ioaddr.error_addr); + } + return inb(ap->ioaddr.error_addr); +} + /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert @@ -878,8 +902,8 @@ static u8 ata_dev_try_classify(struct ata_port *ap, unsigned int device) memset(&tf, 0, sizeof(tf)); + err = ata_chk_err(ap); ap->ops->tf_read(ap, &tf); - err = tf.feature; dev->class = ATA_DEV_NONE; @@ -1116,6 +1140,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) unsigned int major_version; u16 tmp; unsigned long xfer_modes; + u8 status; unsigned int using_edd; DECLARE_COMPLETION(wait); struct ata_queued_cmd *qc; @@ -1169,11 +1194,8 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) else wait_for_completion(&wait); - spin_lock_irqsave(&ap->host_set->lock, flags); - ap->ops->tf_read(ap, &qc->tf); - spin_unlock_irqrestore(&ap->host_set->lock, flags); - - if (qc->tf.command & ATA_ERR) { + 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 @@ -1186,7 +1208,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) * to have this problem. */ if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) { - u8 err = qc->tf.feature; + u8 err = ata_chk_err(ap); if (err & ATA_ABORTED) { dev->class = ATA_DEV_ATAPI; qc->cursg = 0; @@ -2427,9 +2449,8 @@ static void ata_dev_init_params(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); @@ -2439,35 +2460,14 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) DPRINTK("unmapping %u sg elements\n", qc->n_elem); - /* 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->flags & ATA_QCFLAG_SG) dma_unmap_sg(ap->host_set->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(psg->page, KM_IRQ0); - } - } else { + else dma_unmap_single(ap->host_set->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; } /** @@ -2483,15 +2483,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; - struct scatterlist *sg; - unsigned int idx; + unsigned int idx, nelem; - assert(qc->__sg != NULL); + assert(sg != NULL); assert(qc->n_elem > 0); idx = 0; - ata_for_each_sg(sg, qc) { + for (nelem = qc->n_elem; nelem; nelem--,sg++) { u32 addr, offset; u32 sg_len, len; @@ -2577,18 +2577,12 @@ void ata_qc_prep(struct ata_queued_cmd *qc) void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) { - struct scatterlist *sg; - 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_init_one(sg, buf, buflen); + sg_init_one(qc->sg, buf, buflen); } /** @@ -2609,9 +2603,8 @@ 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; } /** @@ -2631,32 +2624,9 @@ 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; - /* 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; - - assert(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; - - DPRINTK("padding done, sg->length=%u pad_len=%u\n", - sg->length, qc->pad_len); - } - dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, sg->length, dir); if (dma_mapping_error(dma_address)) @@ -2688,47 +2658,12 @@ 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; - struct scatterlist *lsg = &sg[qc->n_elem - 1]; + struct scatterlist *sg = qc->sg; int n_elem, dir; VPRINTK("ENTER, ata%u\n", ap->id); assert(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; - - assert(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(psg->page, 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; - - DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", - qc->n_elem - 1, lsg->length, qc->pad_len); - } - dir = qc->dma_dir; n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir); if (n_elem < 1) @@ -2750,7 +2685,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * None. (grabs host lock) */ -void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { struct ata_port *ap = qc->ap; unsigned long flags; @@ -2758,7 +2693,7 @@ void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) spin_lock_irqsave(&ap->host_set->lock, flags); ap->flags &= ~ATA_FLAG_NOINTR; ata_irq_on(ap); - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc, drv_stat); spin_unlock_irqrestore(&ap->host_set->lock, flags); } @@ -2855,7 +2790,7 @@ static int ata_pio_complete (struct ata_port *ap) ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, 0); + ata_poll_qc_complete(qc, drv_stat); /* another command may start at this point */ @@ -3004,7 +2939,7 @@ 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; @@ -3054,7 +2989,7 @@ 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; @@ -3087,7 +3022,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) return; } - sg = &qc->__sg[qc->cursg]; + sg = &qc->sg[qc->cursg]; page = sg->page; offset = sg->offset + qc->cursg_ofs; @@ -3223,15 +3158,18 @@ static void ata_pio_block(struct ata_port *ap) static void ata_pio_error(struct ata_port *ap) { struct ata_queued_cmd *qc; - - printk(KERN_WARNING "ata%u: PIO error\n", ap->id); + u8 drv_stat; qc = ata_qc_from_tag(ap, ap->active_tag); assert(qc != NULL); + drv_stat = ata_chk_status(ap); + printk(KERN_WARNING "ata%u: PIO error, drv_stat 0x%x\n", + ap->id, drv_stat); + ap->hsm_task_state = HSM_ST_IDLE; - ata_poll_qc_complete(qc, AC_ERR_ATA_BUS); + ata_poll_qc_complete(qc, drv_stat | ATA_ERR); } static void ata_pio_task(void *_data) @@ -3354,7 +3292,7 @@ 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, ac_err_mask(drv_stat)); + ata_qc_complete(qc, drv_stat); break; } @@ -3444,7 +3382,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, qc = ata_qc_new(ap); if (qc) { - qc->__sg = NULL; + qc->sg = NULL; qc->flags = 0; qc->scsicmd = NULL; qc->ap = ap; @@ -3459,7 +3397,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, return qc; } -int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask) +int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat) { return 0; } @@ -3518,7 +3456,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) * spin_lock_irqsave(host_set lock) */ -void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { int rc; @@ -3535,7 +3473,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) qc->flags &= ~ATA_QCFLAG_ACTIVE; /* call completion callback */ - rc = qc->complete_fn(qc, err_mask); + rc = qc->complete_fn(qc, drv_stat); /* if callback indicates not to complete command (non-zero), * return immediately @@ -3973,7 +3911,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ap->ops->irq_clear(ap); /* complete taskfile transaction */ - ata_qc_complete(qc, ac_err_mask(status)); + ata_qc_complete(qc, status); break; default: @@ -4068,7 +4006,7 @@ static void atapi_packet_task(void *_data) /* 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_status; + goto err_out; /* make sure DRQ is set */ status = ata_chk_status(ap); @@ -4105,10 +4043,8 @@ static void atapi_packet_task(void *_data) return; -err_out_status: - status = ata_chk_status(ap); err_out: - ata_poll_qc_complete(qc, __ac_err_mask(status)); + ata_poll_qc_complete(qc, ATA_ERR); } @@ -4133,12 +4069,6 @@ int ata_port_start (struct ata_port *ap) if (!ap->prd) return -ENOMEM; - ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); - if (!ap->pad) { - dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); - return -ENOMEM; - } - DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); return 0; @@ -4162,7 +4092,6 @@ void ata_port_stop (struct ata_port *ap) struct device *dev = ap->host_set->dev; dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); - dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); } void ata_host_stop (struct ata_host_set *host_set) @@ -4938,6 +4867,7 @@ 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); diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index 5574520bf1c2..89a04b1a5a0e 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -354,10 +354,10 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap, qc->scsidone = done; if (cmd->use_sg) { - qc->__sg = (struct scatterlist *) cmd->request_buffer; + qc->sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; } else { - qc->__sg = &qc->sgent; + qc->sg = &qc->sgent; qc->n_elem = 1; } } else { @@ -560,7 +560,7 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ - if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[1], &sb[2], &sb[3]); sb[1] &= 0x0f; @@ -635,7 +635,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) * Use ata_to_sense_error() to map status register bits * onto sense key, asc & ascq. */ - if (tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + if (unlikely(tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ))) { ata_to_sense_error(qc->ap->id, tf->command, tf->feature, &sb[2], &sb[12], &sb[13]); sb[2] &= 0x0f; @@ -644,11 +644,7 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[0] = 0x70; sb[7] = 0x0a; - if (tf->flags & ATA_TFLAG_LBA48) { - /* TODO: find solution for LBA48 descriptors */ - } - - else if (tf->flags & ATA_TFLAG_LBA) { + if (tf->flags & ATA_TFLAG_LBA && !(tf->flags & ATA_TFLAG_LBA48)) { /* A small (28b) LBA will fit in the 32b info field */ sb[0] |= 0x80; /* set valid bit */ sb[3] = tf->device & 0x0f; @@ -656,10 +652,6 @@ void ata_gen_fixed_sense(struct ata_queued_cmd *qc) sb[5] = tf->lbam; sb[6] = tf->lbal; } - - else { - /* TODO: C/H/S */ - } } /** @@ -701,16 +693,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev) */ blk_queue_max_sectors(sdev->request_queue, 2048); } - - /* - * SATA DMA transfers must be multiples of 4 byte, so - * we need to pad ATAPI transfers using an extra sg. - * Decrement max hw segments accordingly. - */ - if (dev->class == ATA_DEV_ATAPI) { - request_queue_t *q = sdev->request_queue; - blk_queue_max_hw_segments(q, q->max_hw_segments - 1); - } } return 0; /* scsi layer doesn't check return value, sigh */ @@ -1217,12 +1199,10 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm return 1; } -static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, - unsigned int err_mask) +static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { struct scsi_cmnd *cmd = qc->scsicmd; - u8 *cdb = cmd->cmnd; - int need_sense = (err_mask != 0); + int need_sense = drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ); /* For ATA pass thru (SAT) commands, generate a sense block if * user mandated it or if there's an error. Note that if we @@ -1231,8 +1211,8 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, * whether the command completed successfully or not. If there * was no error, SK, ASC and ASCQ will all be zero. */ - if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && - ((cdb[2] & 0x20) || need_sense)) { + if (((cmd->cmnd[0] == ATA_16) || (cmd->cmnd[0] == ATA_12)) && + ((cmd->cmnd[2] & 0x20) || need_sense)) { ata_gen_ata_desc_sense(qc); } else { if (!need_sense) { @@ -2015,13 +1995,21 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, DPRINTK("EXIT\n"); } -static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) +static int atapi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) { struct scsi_cmnd *cmd = qc->scsicmd; - VPRINTK("ENTER, err_mask 0x%X\n", err_mask); + VPRINTK("ENTER, drv_stat == 0x%x\n", drv_stat); + + if (unlikely(drv_stat & (ATA_BUSY | ATA_DRQ))) + /* FIXME: not quite right; we don't want the + * translation of taskfile registers into + * a sense descriptors, since that's only + * correct for ATA, not ATAPI + */ + ata_gen_ata_desc_sense(qc); - if (unlikely(err_mask & AC_ERR_DEV)) { + else if (unlikely(drv_stat & ATA_ERR)) { DPRINTK("request check condition\n"); /* FIXME: command completion with check condition @@ -2038,14 +2026,6 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) return 1; } - else if (unlikely(err_mask)) - /* FIXME: not quite right; we don't want the - * translation of taskfile registers into - * a sense descriptors, since that's only - * correct for ATA, not ATAPI - */ - ata_gen_ata_desc_sense(qc); - else { u8 *scsicmd = cmd->cmnd; diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index 10ecd9e15e4f..65c264b91136 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -39,7 +39,7 @@ struct ata_scsi_args { /* libata-core.c */ extern int atapi_enabled; -extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask); +extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc); diff --git a/trunk/drivers/scsi/pdc_adma.c b/trunk/drivers/scsi/pdc_adma.c index 988d0d70a277..af99feb9d237 100644 --- a/trunk/drivers/scsi/pdc_adma.c +++ b/trunk/drivers/scsi/pdc_adma.c @@ -292,14 +292,14 @@ static void adma_eng_timeout(struct ata_port *ap) static int adma_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg; + struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; struct adma_port_priv *pp = ap->private_data; u8 *buf = pp->pkt; - int i = (2 + buf[3]) * 8; + int nelem, i = (2 + buf[3]) * 8; u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0); - ata_for_each_sg(sg, qc) { + for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { u32 addr; u32 len; @@ -311,7 +311,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)(buf + i) = cpu_to_le32(len); i += 4; - if (ata_sg_is_last(sg, qc)) + if ((nelem + 1) == qc->n_elem) pFLAGS |= pEND; buf[i++] = pFLAGS; buf[i++] = qc->dev->dma_mode & 0xf; @@ -451,7 +451,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) struct adma_port_priv *pp; struct ata_queued_cmd *qc; void __iomem *chan = ADMA_REGS(mmio_base, port_no); - u8 status = readb(chan + ADMA_STATUS); + u8 drv_stat = 0, status = readb(chan + ADMA_STATUS); if (status == 0) continue; @@ -464,14 +464,11 @@ static inline unsigned int adma_intr_pkt(struct ata_host_set *host_set) continue; qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) { - unsigned int err_mask = 0; - if ((status & (aPERR | aPSD | aUIRQ))) - err_mask = AC_ERR_OTHER; + drv_stat = ATA_ERR; else if (pp->pkt[0] != cDONE) - err_mask = AC_ERR_OTHER; - - ata_qc_complete(qc, err_mask); + drv_stat = ATA_ERR; + ata_qc_complete(qc, drv_stat); } } return handled; @@ -501,7 +498,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ pp->state = adma_state_idle; - ata_qc_complete(qc, ac_err_mask(status)); + ata_qc_complete(qc, status); handled = 1; } } diff --git a/trunk/drivers/scsi/sata_mv.c b/trunk/drivers/scsi/sata_mv.c index a3ab14c79cdd..422e0b6f603a 100644 --- a/trunk/drivers/scsi/sata_mv.c +++ b/trunk/drivers/scsi/sata_mv.c @@ -258,6 +258,7 @@ struct mv_host_priv { static void mv_irq_clear(struct ata_port *ap); static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u8 mv_check_err(struct ata_port *ap); static void mv_phy_reset(struct ata_port *ap); static void mv_host_stop(struct ata_host_set *host_set); static int mv_port_start(struct ata_port *ap); @@ -295,6 +296,7 @@ static const struct ata_port_operations mv_ops = { .tf_load = ata_tf_load, .tf_read = ata_tf_read, .check_status = ata_check_status, + .check_err = mv_check_err, .exec_command = ata_exec_command, .dev_select = ata_std_dev_select, @@ -783,24 +785,23 @@ static void mv_port_stop(struct ata_port *ap) static void mv_fill_sg(struct ata_queued_cmd *qc) { struct mv_port_priv *pp = qc->ap->private_data; - unsigned int i = 0; - struct scatterlist *sg; + unsigned int i; - ata_for_each_sg(sg, qc) { + for (i = 0; i < qc->n_elem; i++) { u32 sg_len; dma_addr_t addr; - addr = sg_dma_address(sg); - sg_len = sg_dma_len(sg); + addr = sg_dma_address(&qc->sg[i]); + sg_len = sg_dma_len(&qc->sg[i]); pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); - if (ata_sg_is_last(sg, qc)) - pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); - - i++; + } + if (0 < qc->n_elem) { + pp->sg_tbl[qc->n_elem - 1].flags_size |= + cpu_to_le32(EPRD_FLAG_END_OF_TBL); } } @@ -1066,7 +1067,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, struct ata_queued_cmd *qc; u32 hc_irq_cause; int shift, port, port0, hard_port, handled; - unsigned int err_mask; u8 ata_status = 0; if (hc == 0) { @@ -1102,15 +1102,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, handled++; } - err_mask = ac_err_mask(ata_status); - shift = port << 1; /* (port * 2) */ if (port >= MV_PORTS_PER_HC) { shift++; /* skip bit 8 in the HC Main IRQ reg */ } if ((PORT0_ERR << shift) & relevant) { mv_err_intr(ap); - err_mask |= AC_ERR_OTHER; + /* OR in ATA_ERR to ensure libata knows we took one */ + ata_status = readb((void __iomem *) + ap->ioaddr.status_addr) | ATA_ERR; handled++; } @@ -1120,7 +1120,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc, ata_status); } } } @@ -1184,6 +1184,22 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, return IRQ_RETVAL(handled); } +/** + * mv_check_err - Return the error shadow register to caller. + * @ap: ATA channel to manipulate + * + * Marvell requires DMA to be stopped before accessing shadow + * registers. So we do that, then return the needed register. + * + * LOCKING: + * Inherited from caller. FIXME: protect mv_stop_dma with lock? + */ +static u8 mv_check_err(struct ata_port *ap) +{ + mv_stop_dma(ap); /* can't read shadow regs if DMA on */ + return readb((void __iomem *) ap->ioaddr.error_addr); +} + /** * mv_phy_reset - Perform eDMA reset followed by COMRESET * @ap: ATA channel to manipulate @@ -1296,7 +1312,7 @@ static void mv_eng_timeout(struct ata_port *ap) */ spin_lock_irqsave(&ap->host_set->lock, flags); qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + ata_qc_complete(qc, ATA_ERR); spin_unlock_irqrestore(&ap->host_set->lock, flags); } } diff --git a/trunk/drivers/scsi/sata_promise.c b/trunk/drivers/scsi/sata_promise.c index 8f41702275db..63911f16b6ec 100644 --- a/trunk/drivers/scsi/sata_promise.c +++ b/trunk/drivers/scsi/sata_promise.c @@ -399,8 +399,7 @@ static void pdc_eng_timeout(struct ata_port *ap) case ATA_PROT_DMA: case ATA_PROT_NODATA: printk(KERN_ERR "ata%u: command timeout\n", ap->id); - drv_stat = ata_wait_idle(ap); - ata_qc_complete(qc, __ac_err_mask(drv_stat)); + ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR); break; default: @@ -409,7 +408,7 @@ static void pdc_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", ap->id, qc->tf.command, drv_stat); - ata_qc_complete(qc, ac_err_mask(drv_stat)); + ata_qc_complete(qc, drv_stat); break; } @@ -421,21 +420,24 @@ static void pdc_eng_timeout(struct ata_port *ap) static inline unsigned int pdc_host_intr( struct ata_port *ap, struct ata_queued_cmd *qc) { - unsigned int handled = 0, err_mask = 0; + u8 status; + unsigned int handled = 0, have_err = 0; u32 tmp; void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL; tmp = readl(mmio); if (tmp & PDC_ERR_MASK) { - err_mask = AC_ERR_DEV; + have_err = 1; pdc_reset_port(ap); } switch (qc->tf.protocol) { case ATA_PROT_DMA: case ATA_PROT_NODATA: - err_mask |= ac_err_mask(ata_wait_idle(ap)); - ata_qc_complete(qc, err_mask); + status = ata_wait_idle(ap); + if (have_err) + status |= ATA_ERR; + ata_qc_complete(qc, status); handled = 1; break; diff --git a/trunk/drivers/scsi/sata_qstor.c b/trunk/drivers/scsi/sata_qstor.c index 8c20229b01b4..1aaf3304d397 100644 --- a/trunk/drivers/scsi/sata_qstor.c +++ b/trunk/drivers/scsi/sata_qstor.c @@ -270,17 +270,16 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) static void qs_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg; + struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; struct qs_port_priv *pp = ap->private_data; unsigned int nelem; u8 *prd = pp->pkt + QS_CPB_BYTES; - assert(qc->__sg != NULL); + assert(sg != NULL); assert(qc->n_elem > 0); - nelem = 0; - ata_for_each_sg(sg, qc) { + for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { u64 addr; u32 len; @@ -294,7 +293,6 @@ static void qs_fill_sg(struct ata_queued_cmd *qc) VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem, (unsigned long long)addr, len); - nelem++; } } @@ -402,12 +400,11 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) { switch (sHST) { - case 0: /* successful CPB */ + case 0: /* sucessful CPB */ case 3: /* device error */ pp->state = qs_state_idle; qs_enter_reg_mode(qc->ap); - ata_qc_complete(qc, - ac_err_mask(sDST)); + ata_qc_complete(qc, sDST); break; default: break; @@ -444,7 +441,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) /* complete taskfile transaction */ pp->state = qs_state_idle; - ata_qc_complete(qc, ac_err_mask(status)); + ata_qc_complete(qc, status); handled = 1; } } diff --git a/trunk/drivers/scsi/sata_sil24.c b/trunk/drivers/scsi/sata_sil24.c index 05ce84286aea..51855d3bac64 100644 --- a/trunk/drivers/scsi/sata_sil24.c +++ b/trunk/drivers/scsi/sata_sil24.c @@ -225,6 +225,7 @@ struct sil24_host_priv { }; static u8 sil24_check_status(struct ata_port *ap); +static u8 sil24_check_err(struct ata_port *ap); static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); @@ -279,6 +280,7 @@ static const struct ata_port_operations sil24_ops = { .check_status = sil24_check_status, .check_altstatus = sil24_check_status, + .check_err = sil24_check_err, .dev_select = ata_noop_dev_select, .tf_read = sil24_tf_read, @@ -361,6 +363,12 @@ static u8 sil24_check_status(struct ata_port *ap) return pp->tf.command; } +static u8 sil24_check_err(struct ata_port *ap) +{ + struct sil24_port_priv *pp = ap->private_data; + return pp->tf.feature; +} + static int sil24_scr_map[] = { [SCR_CONTROL] = 0, [SCR_STATUS] = 1, @@ -410,20 +418,15 @@ static void sil24_phy_reset(struct ata_port *ap) static inline void sil24_fill_sg(struct ata_queued_cmd *qc, struct sil24_cmd_block *cb) { + struct scatterlist *sg = qc->sg; struct sil24_sge *sge = cb->sge; - struct scatterlist *sg; - unsigned int idx = 0; + unsigned i; - ata_for_each_sg(sg, qc) { + for (i = 0; i < qc->n_elem; i++, sg++, sge++) { sge->addr = cpu_to_le64(sg_dma_address(sg)); sge->cnt = cpu_to_le32(sg_dma_len(sg)); - if (ata_sg_is_last(sg, qc)) - sge->flags = cpu_to_le32(SGE_TRM); - else - sge->flags = 0; - - sge++; - idx++; + sge->flags = 0; + sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM); } } @@ -503,7 +506,7 @@ static void sil24_eng_timeout(struct ata_port *ap) qc = ata_qc_from_tag(ap, ap->active_tag); if (!qc) { - printk(KERN_ERR "ata%u: BUG: timeout without command\n", + printk(KERN_ERR "ata%u: BUG: tiemout without command\n", ap->id); return; } @@ -517,7 +520,7 @@ static void sil24_eng_timeout(struct ata_port *ap) */ printk(KERN_ERR "ata%u: command timeout\n", ap->id); qc->scsidone = scsi_finish_command; - ata_qc_complete(qc, AC_ERR_OTHER); + ata_qc_complete(qc, ATA_ERR); sil24_reset_controller(ap); } @@ -528,7 +531,6 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) struct sil24_port_priv *pp = ap->private_data; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; u32 irq_stat, cmd_err, sstatus, serror; - unsigned int err_mask; irq_stat = readl(port + PORT_IRQ_STAT); writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ @@ -556,18 +558,17 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) * Device is reporting error, tf registers are valid. */ sil24_update_tf(ap); - err_mask = ac_err_mask(pp->tf.command); } else { /* * Other errors. libata currently doesn't have any * mechanism to report these errors. Just turn on * ATA_ERR. */ - err_mask = AC_ERR_OTHER; + pp->tf.command = ATA_ERR; } if (qc) - ata_qc_complete(qc, err_mask); + ata_qc_complete(qc, pp->tf.command); sil24_reset_controller(ap); } @@ -592,7 +593,7 @@ static inline void sil24_host_intr(struct ata_port *ap) sil24_update_tf(ap); if (qc) - ata_qc_complete(qc, ac_err_mask(pp->tf.command)); + ata_qc_complete(qc, pp->tf.command); } else sil24_error_intr(ap, slot_stat); } diff --git a/trunk/drivers/scsi/sata_sx4.c b/trunk/drivers/scsi/sata_sx4.c index 8e2e7b8308c0..af08f4f650c1 100644 --- a/trunk/drivers/scsi/sata_sx4.c +++ b/trunk/drivers/scsi/sata_sx4.c @@ -449,14 +449,14 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, static void pdc20621_dma_prep(struct ata_queued_cmd *qc) { - struct scatterlist *sg; + struct scatterlist *sg = qc->sg; struct ata_port *ap = qc->ap; struct pdc_port_priv *pp = ap->private_data; void __iomem *mmio = ap->host_set->mmio_base; struct pdc_host_priv *hpriv = ap->host_set->private_data; void __iomem *dimm_mmio = hpriv->dimm_mmio; unsigned int portno = ap->port_no; - unsigned int i, idx, total_len = 0, sgt_len; + unsigned int i, last, idx, total_len = 0, sgt_len; u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; assert(qc->flags & ATA_QCFLAG_DMAMAP); @@ -469,11 +469,12 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) /* * Build S/G table */ + last = qc->n_elem; idx = 0; - ata_for_each_sg(sg, qc) { - buf[idx++] = cpu_to_le32(sg_dma_address(sg)); - buf[idx++] = cpu_to_le32(sg_dma_len(sg)); - total_len += sg_dma_len(sg); + for (i = 0; i < last; i++) { + buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i])); + buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i])); + total_len += sg_dma_len(&sg[i]); } buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT); sgt_len = idx * 4; @@ -717,7 +718,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ - ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); + ata_qc_complete(qc, ata_wait_idle(ap)); pdc20621_pop_hdma(qc); } @@ -755,7 +756,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id, readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT)); /* get drive status; clear intr; complete txn */ - ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap))); + ata_qc_complete(qc, ata_wait_idle(ap)); pdc20621_pop_hdma(qc); } handled = 1; @@ -765,7 +766,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap, status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); - ata_qc_complete(qc, ac_err_mask(status)); + ata_qc_complete(qc, status); handled = 1; } else { @@ -880,7 +881,7 @@ static void pdc_eng_timeout(struct ata_port *ap) case ATA_PROT_DMA: case ATA_PROT_NODATA: printk(KERN_ERR "ata%u: command timeout\n", ap->id); - ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap))); + ata_qc_complete(qc, ata_wait_idle(ap) | ATA_ERR); break; default: @@ -889,7 +890,7 @@ static void pdc_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n", ap->id, qc->tf.command, drv_stat); - ata_qc_complete(qc, ac_err_mask(drv_stat)); + ata_qc_complete(qc, drv_stat); break; } diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index 6225b78fa65b..00a8a5738858 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -155,10 +155,6 @@ enum { ATA_SHIFT_UDMA = 0, ATA_SHIFT_MWDMA = 8, ATA_SHIFT_PIO = 11, - - /* size of buffer to pad xfers ending on unaligned boundaries */ - ATA_DMA_PAD_SZ = 4, - ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, /* Masks for port functions */ ATA_PORT_PRIMARY = (1 << 0), @@ -176,13 +172,6 @@ enum hsm_task_states { HSM_ST_ERR, }; -enum ata_completion_errors { - AC_ERR_OTHER = (1 << 0), - AC_ERR_DEV = (1 << 1), - AC_ERR_ATA_BUS = (1 << 2), - AC_ERR_HOST_BUS = (1 << 3), -}; - /* forward declarations */ struct scsi_device; struct ata_port_operations; @@ -190,7 +179,7 @@ struct ata_port; struct ata_queued_cmd; /* typedefs */ -typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask); +typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, u8 drv_stat); struct ata_ioports { unsigned long cmd_addr; @@ -253,12 +242,9 @@ struct ata_queued_cmd { unsigned long flags; /* ATA_QCFLAG_xxx */ unsigned int tag; unsigned int n_elem; - unsigned int orig_n_elem; int dma_dir; - unsigned int pad_len; - unsigned int nsect; unsigned int cursect; @@ -269,11 +255,9 @@ struct ata_queued_cmd { unsigned int cursg_ofs; struct scatterlist sgent; - struct scatterlist pad_sgent; void *buf_virt; - /* DO NOT iterate over __sg manually, use ata_for_each_sg() */ - struct scatterlist *__sg; + struct scatterlist *sg; ata_qc_cb_t complete_fn; @@ -319,9 +303,6 @@ struct ata_port { struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ - void *pad; /* array of DMA pad buffers */ - dma_addr_t pad_dma; - struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ u8 ctl; /* cache of ATA control register */ @@ -366,6 +347,7 @@ struct ata_port_operations { void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf); u8 (*check_status)(struct ata_port *ap); u8 (*check_altstatus)(struct ata_port *ap); + u8 (*check_err)(struct ata_port *ap); void (*dev_select)(struct ata_port *ap, unsigned int device); void (*phy_reset) (struct ata_port *ap); @@ -452,6 +434,7 @@ extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); extern u8 ata_altstatus(struct ata_port *ap); +extern u8 ata_chk_err(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); @@ -472,7 +455,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); -extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask); +extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); extern void ata_eng_timeout(struct ata_port *ap); extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -524,31 +507,6 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit #endif /* CONFIG_PCI */ -static inline int -ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) -{ - if (sg == &qc->pad_sgent) - return 1; - if (qc->pad_len) - return 0; - if (((sg - qc->__sg) + 1) == qc->n_elem) - return 1; - return 0; -} - -static inline struct scatterlist * -ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) -{ - if (sg == &qc->pad_sgent) - return NULL; - if (++sg - qc->__sg < qc->n_elem) - return sg; - return qc->pad_len ? &qc->pad_sgent : NULL; -} - -#define ata_for_each_sg(sg, qc) \ - for (sg = qc->__sg; sg; sg = ata_qc_next_sg(sg, qc)) - static inline unsigned int ata_tag_valid(unsigned int tag) { return (tag < ATA_MAX_QUEUE) ? 1 : 0; @@ -760,21 +718,4 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) ata_id_has_flush_ext(dev->id); } -static inline unsigned int ac_err_mask(u8 status) -{ - if (status & ATA_BUSY) - return AC_ERR_ATA_BUS; - if (status & (ATA_ERR | ATA_DF)) - return AC_ERR_DEV; - return 0; -} - -static inline unsigned int __ac_err_mask(u8 status) -{ - unsigned int mask = ac_err_mask(status); - if (mask == 0) - return AC_ERR_OTHER; - return mask; -} - #endif /* __LINUX_LIBATA_H__ */