diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 80 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 2 | ||||
| -rw-r--r-- | drivers/ata/pata_cs5520.c | 4 | ||||
| -rw-r--r-- | drivers/ata/pata_cs5530.c | 4 | ||||
| -rw-r--r-- | drivers/ata/pata_sc1200.c | 4 | ||||
| -rw-r--r-- | include/linux/libata.h | 2 |
6 files changed, 89 insertions, 7 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 74c4cd9ad82b..5b25311ba885 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -4103,6 +4103,68 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) | |||
| 4103 | } | 4103 | } |
| 4104 | 4104 | ||
| 4105 | /** | 4105 | /** |
| 4106 | * ata_fill_sg_dumb - Fill PCI IDE PRD table | ||
| 4107 | * @qc: Metadata associated with taskfile to be transferred | ||
| 4108 | * | ||
| 4109 | * Fill PCI IDE PRD (scatter-gather) table with segments | ||
| 4110 | * associated with the current disk command. Perform the fill | ||
| 4111 | * so that we avoid writing any length 64K records for | ||
| 4112 | * controllers that don't follow the spec. | ||
| 4113 | * | ||
| 4114 | * LOCKING: | ||
| 4115 | * spin_lock_irqsave(host lock) | ||
| 4116 | * | ||
| 4117 | */ | ||
| 4118 | static void ata_fill_sg_dumb(struct ata_queued_cmd *qc) | ||
| 4119 | { | ||
| 4120 | struct ata_port *ap = qc->ap; | ||
| 4121 | struct scatterlist *sg; | ||
| 4122 | unsigned int idx; | ||
| 4123 | |||
| 4124 | WARN_ON(qc->__sg == NULL); | ||
| 4125 | WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); | ||
| 4126 | |||
| 4127 | idx = 0; | ||
| 4128 | ata_for_each_sg(sg, qc) { | ||
| 4129 | u32 addr, offset; | ||
| 4130 | u32 sg_len, len, blen; | ||
| 4131 | |||
| 4132 | /* determine if physical DMA addr spans 64K boundary. | ||
| 4133 | * Note h/w doesn't support 64-bit, so we unconditionally | ||
| 4134 | * truncate dma_addr_t to u32. | ||
| 4135 | */ | ||
| 4136 | addr = (u32) sg_dma_address(sg); | ||
| 4137 | sg_len = sg_dma_len(sg); | ||
| 4138 | |||
| 4139 | while (sg_len) { | ||
| 4140 | offset = addr & 0xffff; | ||
| 4141 | len = sg_len; | ||
| 4142 | if ((offset + sg_len) > 0x10000) | ||
| 4143 | len = 0x10000 - offset; | ||
| 4144 | |||
| 4145 | blen = len & 0xffff; | ||
| 4146 | ap->prd[idx].addr = cpu_to_le32(addr); | ||
| 4147 | if (blen == 0) { | ||
| 4148 | /* Some PATA chipsets like the CS5530 can't | ||
| 4149 | cope with 0x0000 meaning 64K as the spec says */ | ||
| 4150 | ap->prd[idx].flags_len = cpu_to_le32(0x8000); | ||
| 4151 | blen = 0x8000; | ||
| 4152 | ap->prd[++idx].addr = cpu_to_le32(addr + 0x8000); | ||
| 4153 | } | ||
| 4154 | ap->prd[idx].flags_len = cpu_to_le32(blen); | ||
| 4155 | VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len); | ||
| 4156 | |||
| 4157 | idx++; | ||
| 4158 | sg_len -= len; | ||
| 4159 | addr += len; | ||
| 4160 | } | ||
| 4161 | } | ||
| 4162 | |||
| 4163 | if (idx) | ||
| 4164 | ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); | ||
| 4165 | } | ||
| 4166 | |||
| 4167 | /** | ||
| 4106 | * ata_check_atapi_dma - Check whether ATAPI DMA can be supported | 4168 | * ata_check_atapi_dma - Check whether ATAPI DMA can be supported |
| 4107 | * @qc: Metadata associated with taskfile to check | 4169 | * @qc: Metadata associated with taskfile to check |
| 4108 | * | 4170 | * |
| @@ -4149,6 +4211,23 @@ void ata_qc_prep(struct ata_queued_cmd *qc) | |||
| 4149 | ata_fill_sg(qc); | 4211 | ata_fill_sg(qc); |
| 4150 | } | 4212 | } |
| 4151 | 4213 | ||
| 4214 | /** | ||
| 4215 | * ata_dumb_qc_prep - Prepare taskfile for submission | ||
| 4216 | * @qc: Metadata associated with taskfile to be prepared | ||
| 4217 | * | ||
| 4218 | * Prepare ATA taskfile for submission. | ||
| 4219 | * | ||
| 4220 | * LOCKING: | ||
| 4221 | * spin_lock_irqsave(host lock) | ||
| 4222 | */ | ||
| 4223 | void ata_dumb_qc_prep(struct ata_queued_cmd *qc) | ||
| 4224 | { | ||
| 4225 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) | ||
| 4226 | return; | ||
| 4227 | |||
| 4228 | ata_fill_sg_dumb(qc); | ||
| 4229 | } | ||
| 4230 | |||
| 4152 | void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } | 4231 | void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } |
| 4153 | 4232 | ||
| 4154 | /** | 4233 | /** |
| @@ -6821,6 +6900,7 @@ EXPORT_SYMBOL_GPL(ata_do_set_mode); | |||
| 6821 | EXPORT_SYMBOL_GPL(ata_data_xfer); | 6900 | EXPORT_SYMBOL_GPL(ata_data_xfer); |
| 6822 | EXPORT_SYMBOL_GPL(ata_data_xfer_noirq); | 6901 | EXPORT_SYMBOL_GPL(ata_data_xfer_noirq); |
| 6823 | EXPORT_SYMBOL_GPL(ata_qc_prep); | 6902 | EXPORT_SYMBOL_GPL(ata_qc_prep); |
| 6903 | EXPORT_SYMBOL_GPL(ata_dumb_qc_prep); | ||
| 6824 | EXPORT_SYMBOL_GPL(ata_noop_qc_prep); | 6904 | EXPORT_SYMBOL_GPL(ata_noop_qc_prep); |
| 6825 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); | 6905 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); |
| 6826 | EXPORT_SYMBOL_GPL(ata_bmdma_start); | 6906 | EXPORT_SYMBOL_GPL(ata_bmdma_start); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4ddf00c8c5f5..cfde22da07ac 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -2620,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
| 2620 | ata_dev_printk(dev, KERN_WARNING, | 2620 | ata_dev_printk(dev, KERN_WARNING, |
| 2621 | "invalid multi_count %u ignored\n", | 2621 | "invalid multi_count %u ignored\n", |
| 2622 | multi_count); | 2622 | multi_count); |
| 2623 | } | 2623 | } |
| 2624 | 2624 | ||
| 2625 | /* READ/WRITE LONG use a non-standard sect_size */ | 2625 | /* READ/WRITE LONG use a non-standard sect_size */ |
| 2626 | qc->sect_size = ATA_SECT_SIZE; | 2626 | qc->sect_size = ATA_SECT_SIZE; |
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 00cf0134079c..6bf037d82b5a 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c | |||
| @@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = { | |||
| 146 | .queuecommand = ata_scsi_queuecmd, | 146 | .queuecommand = ata_scsi_queuecmd, |
| 147 | .can_queue = ATA_DEF_QUEUE, | 147 | .can_queue = ATA_DEF_QUEUE, |
| 148 | .this_id = ATA_SHT_THIS_ID, | 148 | .this_id = ATA_SHT_THIS_ID, |
| 149 | .sg_tablesize = LIBATA_MAX_PRD, | 149 | .sg_tablesize = LIBATA_DUMB_MAX_PRD, |
| 150 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 150 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
| 151 | .emulated = ATA_SHT_EMULATED, | 151 | .emulated = ATA_SHT_EMULATED, |
| 152 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 152 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
| @@ -178,7 +178,7 @@ static struct ata_port_operations cs5520_port_ops = { | |||
| 178 | .bmdma_start = ata_bmdma_start, | 178 | .bmdma_start = ata_bmdma_start, |
| 179 | .bmdma_stop = ata_bmdma_stop, | 179 | .bmdma_stop = ata_bmdma_stop, |
| 180 | .bmdma_status = ata_bmdma_status, | 180 | .bmdma_status = ata_bmdma_status, |
| 181 | .qc_prep = ata_qc_prep, | 181 | .qc_prep = ata_dumb_qc_prep, |
| 182 | .qc_issue = ata_qc_issue_prot, | 182 | .qc_issue = ata_qc_issue_prot, |
| 183 | .data_xfer = ata_data_xfer, | 183 | .data_xfer = ata_data_xfer, |
| 184 | 184 | ||
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 797a6f67e8f5..3fca5898642b 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c | |||
| @@ -167,7 +167,7 @@ static struct scsi_host_template cs5530_sht = { | |||
| 167 | .queuecommand = ata_scsi_queuecmd, | 167 | .queuecommand = ata_scsi_queuecmd, |
| 168 | .can_queue = ATA_DEF_QUEUE, | 168 | .can_queue = ATA_DEF_QUEUE, |
| 169 | .this_id = ATA_SHT_THIS_ID, | 169 | .this_id = ATA_SHT_THIS_ID, |
| 170 | .sg_tablesize = LIBATA_MAX_PRD, | 170 | .sg_tablesize = LIBATA_DUMB_MAX_PRD, |
| 171 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 171 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
| 172 | .emulated = ATA_SHT_EMULATED, | 172 | .emulated = ATA_SHT_EMULATED, |
| 173 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 173 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
| @@ -201,7 +201,7 @@ static struct ata_port_operations cs5530_port_ops = { | |||
| 201 | .post_internal_cmd = ata_bmdma_post_internal_cmd, | 201 | .post_internal_cmd = ata_bmdma_post_internal_cmd, |
| 202 | .cable_detect = ata_cable_40wire, | 202 | .cable_detect = ata_cable_40wire, |
| 203 | 203 | ||
| 204 | .qc_prep = ata_qc_prep, | 204 | .qc_prep = ata_dumb_qc_prep, |
| 205 | .qc_issue = cs5530_qc_issue_prot, | 205 | .qc_issue = cs5530_qc_issue_prot, |
| 206 | 206 | ||
| 207 | .data_xfer = ata_data_xfer, | 207 | .data_xfer = ata_data_xfer, |
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 7ff39cf9dc0b..b8b2d11e4180 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c | |||
| @@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = { | |||
| 185 | .queuecommand = ata_scsi_queuecmd, | 185 | .queuecommand = ata_scsi_queuecmd, |
| 186 | .can_queue = ATA_DEF_QUEUE, | 186 | .can_queue = ATA_DEF_QUEUE, |
| 187 | .this_id = ATA_SHT_THIS_ID, | 187 | .this_id = ATA_SHT_THIS_ID, |
| 188 | .sg_tablesize = LIBATA_MAX_PRD, | 188 | .sg_tablesize = LIBATA_DUMB_MAX_PRD, |
| 189 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 189 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
| 190 | .emulated = ATA_SHT_EMULATED, | 190 | .emulated = ATA_SHT_EMULATED, |
| 191 | .use_clustering = ATA_SHT_USE_CLUSTERING, | 191 | .use_clustering = ATA_SHT_USE_CLUSTERING, |
| @@ -219,7 +219,7 @@ static struct ata_port_operations sc1200_port_ops = { | |||
| 219 | .bmdma_stop = ata_bmdma_stop, | 219 | .bmdma_stop = ata_bmdma_stop, |
| 220 | .bmdma_status = ata_bmdma_status, | 220 | .bmdma_status = ata_bmdma_status, |
| 221 | 221 | ||
| 222 | .qc_prep = ata_qc_prep, | 222 | .qc_prep = ata_dumb_qc_prep, |
| 223 | .qc_issue = sc1200_qc_issue_prot, | 223 | .qc_issue = sc1200_qc_issue_prot, |
| 224 | 224 | ||
| 225 | .data_xfer = ata_data_xfer, | 225 | .data_xfer = ata_data_xfer, |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 8d3e391ab8d3..a3df64677ac3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -116,6 +116,7 @@ static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) | |||
| 116 | enum { | 116 | enum { |
| 117 | /* various global constants */ | 117 | /* various global constants */ |
| 118 | LIBATA_MAX_PRD = ATA_MAX_PRD / 2, | 118 | LIBATA_MAX_PRD = ATA_MAX_PRD / 2, |
| 119 | LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */ | ||
| 119 | ATA_MAX_PORTS = 8, | 120 | ATA_MAX_PORTS = 8, |
| 120 | ATA_DEF_QUEUE = 1, | 121 | ATA_DEF_QUEUE = 1, |
| 121 | /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ | 122 | /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ |
| @@ -778,6 +779,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
| 778 | unsigned int buflen, int write_data); | 779 | unsigned int buflen, int write_data); |
| 779 | extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, | 780 | extern void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, |
| 780 | unsigned int buflen, int write_data); | 781 | unsigned int buflen, int write_data); |
| 782 | extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc); | ||
| 781 | extern void ata_qc_prep(struct ata_queued_cmd *qc); | 783 | extern void ata_qc_prep(struct ata_queued_cmd *qc); |
| 782 | extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); | 784 | extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); |
| 783 | extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); | 785 | extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); |
