diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 76 |
1 files changed, 33 insertions, 43 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f46eb6f6dc9f..a109ccbda9ca 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4675,24 +4675,9 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) | |||
4675 | */ | 4675 | */ |
4676 | static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) | 4676 | static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) |
4677 | { | 4677 | { |
4678 | if (qc->tf.protocol != ATAPI_PROT_PIO && | 4678 | return ata_is_atapi(qc->tf.protocol) && ata_is_data(qc->tf.protocol) && |
4679 | qc->tf.protocol != ATAPI_PROT_DMA) | 4679 | atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC && |
4680 | return 0; | 4680 | !(qc->tf.flags & ATA_TFLAG_WRITE); |
4681 | |||
4682 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
4683 | return 0; | ||
4684 | |||
4685 | switch (qc->cdb[0]) { | ||
4686 | case READ_10: | ||
4687 | case READ_12: | ||
4688 | case WRITE_10: | ||
4689 | case WRITE_12: | ||
4690 | case GPCMD_READ_CD: | ||
4691 | case GPCMD_READ_CD_MSF: | ||
4692 | return 0; | ||
4693 | } | ||
4694 | |||
4695 | return 1; | ||
4696 | } | 4681 | } |
4697 | 4682 | ||
4698 | /** | 4683 | /** |
@@ -5146,13 +5131,14 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
5146 | */ | 5131 | */ |
5147 | static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | 5132 | static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) |
5148 | { | 5133 | { |
5149 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | 5134 | int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ; |
5150 | struct ata_port *ap = qc->ap; | 5135 | struct ata_port *ap = qc->ap; |
5151 | struct ata_eh_info *ehi = &qc->dev->link->eh_info; | 5136 | struct ata_device *dev = qc->dev; |
5137 | struct ata_eh_info *ehi = &dev->link->eh_info; | ||
5152 | struct scatterlist *sg; | 5138 | struct scatterlist *sg; |
5153 | struct page *page; | 5139 | struct page *page; |
5154 | unsigned char *buf; | 5140 | unsigned char *buf; |
5155 | unsigned int offset, count; | 5141 | unsigned int offset, count, consumed; |
5156 | 5142 | ||
5157 | next_sg: | 5143 | next_sg: |
5158 | sg = qc->cursg; | 5144 | sg = qc->cursg; |
@@ -5165,26 +5151,27 @@ next_sg: | |||
5165 | * - for write case, padding zero data to the device | 5151 | * - for write case, padding zero data to the device |
5166 | */ | 5152 | */ |
5167 | u16 pad_buf[1] = { 0 }; | 5153 | u16 pad_buf[1] = { 0 }; |
5168 | unsigned int i; | ||
5169 | 5154 | ||
5170 | if (bytes > qc->curbytes - qc->nbytes + ATAPI_MAX_DRAIN) { | 5155 | if (qc->curbytes + bytes > qc->nbytes + ATAPI_MAX_DRAIN) { |
5171 | ata_ehi_push_desc(ehi, "too much trailing data " | 5156 | ata_ehi_push_desc(ehi, "too much trailing data " |
5172 | "buf=%u cur=%u bytes=%u", | 5157 | "buf=%u cur=%u bytes=%u", |
5173 | qc->nbytes, qc->curbytes, bytes); | 5158 | qc->nbytes, qc->curbytes, bytes); |
5174 | return -1; | 5159 | return -1; |
5175 | } | 5160 | } |
5176 | 5161 | ||
5177 | /* overflow is exptected for misc ATAPI commands */ | 5162 | /* allow overflow only for misc ATAPI commands */ |
5178 | if (bytes && !atapi_qc_may_overflow(qc)) | 5163 | if (!atapi_qc_may_overflow(qc)) { |
5179 | ata_dev_printk(qc->dev, KERN_WARNING, "ATAPI %u bytes " | 5164 | ata_ehi_push_desc(ehi, "unexpected trailing data " |
5180 | "trailing data (cdb=%02x nbytes=%u)\n", | 5165 | "%u bytes", bytes); |
5181 | bytes, qc->cdb[0], qc->nbytes); | 5166 | return -1; |
5167 | } | ||
5182 | 5168 | ||
5183 | for (i = 0; i < (bytes + 1) / 2; i++) | 5169 | consumed = 0; |
5184 | ap->ops->data_xfer(qc->dev, (unsigned char *)pad_buf, 2, do_write); | 5170 | while (consumed < bytes) |
5171 | consumed += ap->ops->data_xfer(dev, | ||
5172 | (unsigned char *)pad_buf, 2, rw); | ||
5185 | 5173 | ||
5186 | qc->curbytes += bytes; | 5174 | qc->curbytes += bytes; |
5187 | |||
5188 | return 0; | 5175 | return 0; |
5189 | } | 5176 | } |
5190 | 5177 | ||
@@ -5211,18 +5198,16 @@ next_sg: | |||
5211 | buf = kmap_atomic(page, KM_IRQ0); | 5198 | buf = kmap_atomic(page, KM_IRQ0); |
5212 | 5199 | ||
5213 | /* do the actual data transfer */ | 5200 | /* do the actual data transfer */ |
5214 | ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); | 5201 | consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); |
5215 | 5202 | ||
5216 | kunmap_atomic(buf, KM_IRQ0); | 5203 | kunmap_atomic(buf, KM_IRQ0); |
5217 | local_irq_restore(flags); | 5204 | local_irq_restore(flags); |
5218 | } else { | 5205 | } else { |
5219 | buf = page_address(page); | 5206 | buf = page_address(page); |
5220 | ap->ops->data_xfer(qc->dev, buf + offset, count, do_write); | 5207 | consumed = ap->ops->data_xfer(dev, buf + offset, count, rw); |
5221 | } | 5208 | } |
5222 | 5209 | ||
5223 | bytes -= count; | 5210 | bytes -= min(bytes, consumed); |
5224 | if ((count & 1) && bytes) | ||
5225 | bytes--; | ||
5226 | qc->curbytes += count; | 5211 | qc->curbytes += count; |
5227 | qc->cursg_ofs += count; | 5212 | qc->cursg_ofs += count; |
5228 | 5213 | ||
@@ -5231,9 +5216,11 @@ next_sg: | |||
5231 | qc->cursg_ofs = 0; | 5216 | qc->cursg_ofs = 0; |
5232 | } | 5217 | } |
5233 | 5218 | ||
5219 | /* consumed can be larger than count only for the last transfer */ | ||
5220 | WARN_ON(qc->cursg && count != consumed); | ||
5221 | |||
5234 | if (bytes) | 5222 | if (bytes) |
5235 | goto next_sg; | 5223 | goto next_sg; |
5236 | |||
5237 | return 0; | 5224 | return 0; |
5238 | } | 5225 | } |
5239 | 5226 | ||
@@ -5251,6 +5238,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) | |||
5251 | { | 5238 | { |
5252 | struct ata_port *ap = qc->ap; | 5239 | struct ata_port *ap = qc->ap; |
5253 | struct ata_device *dev = qc->dev; | 5240 | struct ata_device *dev = qc->dev; |
5241 | struct ata_eh_info *ehi = &dev->link->eh_info; | ||
5254 | unsigned int ireason, bc_lo, bc_hi, bytes; | 5242 | unsigned int ireason, bc_lo, bc_hi, bytes; |
5255 | int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; | 5243 | int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0; |
5256 | 5244 | ||
@@ -5268,26 +5256,28 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) | |||
5268 | 5256 | ||
5269 | /* shall be cleared to zero, indicating xfer of data */ | 5257 | /* shall be cleared to zero, indicating xfer of data */ |
5270 | if (unlikely(ireason & (1 << 0))) | 5258 | if (unlikely(ireason & (1 << 0))) |
5271 | goto err_out; | 5259 | goto atapi_check; |
5272 | 5260 | ||
5273 | /* make sure transfer direction matches expected */ | 5261 | /* make sure transfer direction matches expected */ |
5274 | i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0; | 5262 | i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0; |
5275 | if (unlikely(do_write != i_write)) | 5263 | if (unlikely(do_write != i_write)) |
5276 | goto err_out; | 5264 | goto atapi_check; |
5277 | 5265 | ||
5278 | if (unlikely(!bytes)) | 5266 | if (unlikely(!bytes)) |
5279 | goto err_out; | 5267 | goto atapi_check; |
5280 | 5268 | ||
5281 | VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); | 5269 | VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes); |
5282 | 5270 | ||
5283 | if (__atapi_pio_bytes(qc, bytes)) | 5271 | if (unlikely(__atapi_pio_bytes(qc, bytes))) |
5284 | goto err_out; | 5272 | goto err_out; |
5285 | ata_altstatus(ap); /* flush */ | 5273 | ata_altstatus(ap); /* flush */ |
5286 | 5274 | ||
5287 | return; | 5275 | return; |
5288 | 5276 | ||
5289 | err_out: | 5277 | atapi_check: |
5290 | ata_dev_printk(dev, KERN_INFO, "ATAPI check failed\n"); | 5278 | ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)", |
5279 | ireason, bytes); | ||
5280 | err_out: | ||
5291 | qc->err_mask |= AC_ERR_HSM; | 5281 | qc->err_mask |= AC_ERR_HSM; |
5292 | ap->hsm_task_state = HSM_ST_ERR; | 5282 | ap->hsm_task_state = HSM_ST_ERR; |
5293 | } | 5283 | } |