X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fata%2Flibata-core.c;h=c1444d8f92c69c36efade7c4858b989b5d0e637e;hb=726f0785b608d09bdd64bdbadc09217ebbf9920e;hp=8816e30fb7a42d978e0cf6eba687f25090368b65;hpb=dd8856bda5f1308beb113281b248683992998a9e;p=powerpc.git diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8816e30fb7..c1444d8f92 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1037,7 +1037,7 @@ static unsigned int ata_id_xfermask(const u16 *id) * the PIO timing number for the maximum. Turn it into * a mask. */ - u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF; + u8 mode = (id[ATA_ID_OLD_PIO_MODES] >> 8) & 0xFF; if (mode < 5) /* Valid PIO range */ pio_mask = (2 << mode) - 1; else @@ -1156,7 +1156,7 @@ void ata_port_flush_task(struct ata_port *ap) ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); } -void ata_qc_complete_internal(struct ata_queued_cmd *qc) +static void ata_qc_complete_internal(struct ata_queued_cmd *qc) { struct completion *waiting = qc->private_data; @@ -1249,7 +1249,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, buflen += sg[i].length; ata_sg_init(qc, sg, n_elem); - qc->nsect = buflen / ATA_SECT_SIZE; + qc->nbytes = buflen; } qc->private_data = &wait; @@ -1332,7 +1332,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, } /** - * ata_exec_internal_sg - execute libata internal command + * ata_exec_internal - execute libata internal command * @dev: Device to which the command is sent * @tf: Taskfile registers for the command and the result * @cdb: CDB for packet command @@ -1353,11 +1353,17 @@ unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen) { - struct scatterlist sg; + struct scatterlist *psg = NULL, sg; + unsigned int n_elem = 0; - sg_init_one(&sg, buf, buflen); + if (dma_dir != DMA_NONE) { + WARN_ON(!buf); + sg_init_one(&sg, buf, buflen); + psg = &sg; + n_elem++; + } - return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1); + return ata_exec_internal_sg(dev, tf, cdb, dma_dir, psg, n_elem); } /** @@ -2303,7 +2309,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, * DMA cycle timing is slower/equal than the fastest PIO timing. */ - if (speed > XFER_PIO_4) { + if (speed > XFER_PIO_6) { ata_timing_compute(adev, adev->pio_mode, &p, T, UT); ata_timing_merge(&p, t, t, ATA_TIMING_ALL); } @@ -2425,18 +2431,8 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev) int i, rc = 0, used_dma = 0, found = 0; /* has private set_mode? */ - if (ap->ops->set_mode) { - /* FIXME: make ->set_mode handle no device case and - * return error code and failing device on failure. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - if (ata_dev_ready(&ap->device[i])) { - ap->ops->set_mode(ap); - break; - } - } - return 0; - } + if (ap->ops->set_mode) + return ap->ops->set_mode(ap, r_failed_dev); /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { @@ -3190,7 +3186,8 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, const u16 *new_id) { const u16 *old_id = dev->id; - unsigned char model[2][41], serial[2][21]; + unsigned char model[2][ATA_ID_PROD_LEN + 1]; + unsigned char serial[2][ATA_ID_SERNO_LEN + 1]; u64 new_n_sectors; if (dev->class != new_class) { @@ -3199,10 +3196,10 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, return 0; } - 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])); + ata_id_c_string(old_id, model[0], ATA_ID_PROD, sizeof(model[0])); + ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1])); + ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0])); + ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1])); new_n_sectors = ata_id_n_sectors(new_id); if (strcmp(model[0], model[1])) { @@ -3327,37 +3324,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { } }; -static int ata_strim(char *s, size_t len) -{ - len = strnlen(s, len); - - /* ATAPI specifies that empty space is blank-filled; remove blanks */ - while ((len > 0) && (s[len - 1] == ' ')) { - len--; - s[len] = 0; - } - return len; -} - unsigned long ata_device_blacklisted(const struct ata_device *dev) { - unsigned char model_num[40]; - unsigned char model_rev[16]; - unsigned int nlen, rlen; + unsigned char model_num[ATA_ID_PROD_LEN + 1]; + unsigned char model_rev[ATA_ID_FW_REV_LEN + 1]; const struct ata_blacklist_entry *ad = ata_device_blacklist; - 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)); + ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); + ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev)); while (ad->model_num) { - if (!strncmp(ad->model_num, model_num, nlen)) { + if (!strcmp(ad->model_num, model_num)) { if (ad->model_rev == NULL) return ad->horkage; - if (!strncmp(ad->model_rev, model_rev, rlen)) + if (!strcmp(ad->model_rev, model_rev)) return ad->horkage; } ad++; @@ -4025,11 +4005,11 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) unsigned int offset; unsigned char *buf; - if (qc->cursect == (qc->nsect - 1)) + if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE) ap->hsm_task_state = HSM_ST_LAST; page = sg[qc->cursg].page; - offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE; + offset = sg[qc->cursg].offset + qc->cursg_ofs; /* get the current page and offset */ page = nth_page(page, (offset >> PAGE_SHIFT)); @@ -4054,10 +4034,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write); } - qc->cursect++; - qc->cursg_ofs++; + qc->curbytes += ATA_SECT_SIZE; + qc->cursg_ofs += ATA_SECT_SIZE; - if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) { + if (qc->cursg_ofs == (&sg[qc->cursg])->length) { qc->cursg++; qc->cursg_ofs = 0; } @@ -4082,7 +4062,8 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) WARN_ON(qc->dev->multi_count == 0); - nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count); + nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE, + qc->dev->multi_count); while (nsect--) ata_pio_sector(qc); } else @@ -4960,6 +4941,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc) if (ap->flags & ATA_FLAG_PIO_POLLING) { switch (qc->tf.protocol) { case ATA_PROT_PIO: + case ATA_PROT_NODATA: case ATA_PROT_ATAPI: case ATA_PROT_ATAPI_NODATA: qc->tf.flags |= ATA_TFLAG_POLLING; @@ -5772,7 +5754,7 @@ int ata_device_add(const struct ata_probe_ent *ent) int rc; DPRINTK("ENTER\n"); - + if (ent->irq == 0) { dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); return 0; @@ -6214,12 +6196,22 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) } } -void ata_pci_device_do_resume(struct pci_dev *pdev) +int ata_pci_device_do_resume(struct pci_dev *pdev) { + int rc; + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - pci_enable_device(pdev); + + rc = pci_enable_device(pdev); + if (rc) { + dev_printk(KERN_ERR, &pdev->dev, + "failed to enable device after resume (%d)\n", rc); + return rc; + } + pci_set_master(pdev); + return 0; } int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) @@ -6239,10 +6231,12 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) int ata_pci_device_resume(struct pci_dev *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; - ata_pci_device_do_resume(pdev); - ata_host_resume(host); - return 0; + rc = ata_pci_device_do_resume(pdev); + if (rc == 0) + ata_host_resume(host); + return rc; } #endif /* CONFIG_PCI */