aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-02-19 05:35:37 -0500
committerJens Axboe <jens.axboe@oracle.com>2008-02-19 05:35:37 -0500
commit56c819df77f96c3fc0c2a979e12b478403728790 (patch)
tree104a8538980dbb267a9a26cb4c34eae583cedeb3
parente164094964e6e20fe7fce418e06a9dce952bb7a4 (diff)
libata: update ATAPI overflow draining
For misc ATAPI commands which transfer variable length data to the host, overflow can occur due to application or hardware bug. Such overflows can be ignored safely as long as overflow data is properly drained. libata HSM implementation has this implemented in __atapi_pio_bytes() and recently updated for 2.6.24-rc but it requires further improvements. Improve drain logic such that... * Report overflow errors using ehi desc mechanism instead of printing directly. * Properly calculate the number of bytes to be drained considering actual number of consumed bytes for partial draining. Signed-off-by: Tejun Heo <htejun@gmail.com> Acked-by: Albert Lee <albertcc@tw.ibm.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--drivers/ata/libata-core.c76
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 */
4676static int atapi_qc_may_overflow(struct ata_queued_cmd *qc) 4676static 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 */
5147static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) 5132static 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
5157next_sg: 5143next_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
5289err_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}