ide-atapi.c revision 2ac07d920604eeee8966d52e70161f9b31fe90a3
1/* 2 * ATAPI support. 3 */ 4 5#include <linux/kernel.h> 6#include <linux/delay.h> 7#include <linux/ide.h> 8#include <scsi/scsi.h> 9 10#ifdef DEBUG 11#define debug_log(fmt, args...) \ 12 printk(KERN_INFO "ide: " fmt, ## args) 13#else 14#define debug_log(fmt, args...) do {} while (0) 15#endif 16 17/* 18 * Check whether we can support a device, 19 * based on the ATAPI IDENTIFY command results. 20 */ 21int ide_check_atapi_device(ide_drive_t *drive, const char *s) 22{ 23 u16 *id = drive->id; 24 u8 gcw[2], protocol, device_type, removable, drq_type, packet_size; 25 26 *((u16 *)&gcw) = id[ATA_ID_CONFIG]; 27 28 protocol = (gcw[1] & 0xC0) >> 6; 29 device_type = gcw[1] & 0x1F; 30 removable = (gcw[0] & 0x80) >> 7; 31 drq_type = (gcw[0] & 0x60) >> 5; 32 packet_size = gcw[0] & 0x03; 33 34#ifdef CONFIG_PPC 35 /* kludge for Apple PowerBook internal zip */ 36 if (drive->media == ide_floppy && device_type == 5 && 37 !strstr((char *)&id[ATA_ID_PROD], "CD-ROM") && 38 strstr((char *)&id[ATA_ID_PROD], "ZIP")) 39 device_type = 0; 40#endif 41 42 if (protocol != 2) 43 printk(KERN_ERR "%s: %s: protocol (0x%02x) is not ATAPI\n", 44 s, drive->name, protocol); 45 else if ((drive->media == ide_floppy && device_type != 0) || 46 (drive->media == ide_tape && device_type != 1)) 47 printk(KERN_ERR "%s: %s: invalid device type (0x%02x)\n", 48 s, drive->name, device_type); 49 else if (removable == 0) 50 printk(KERN_ERR "%s: %s: the removable flag is not set\n", 51 s, drive->name); 52 else if (drive->media == ide_floppy && drq_type == 3) 53 printk(KERN_ERR "%s: %s: sorry, DRQ type (0x%02x) not " 54 "supported\n", s, drive->name, drq_type); 55 else if (packet_size != 0) 56 printk(KERN_ERR "%s: %s: packet size (0x%02x) is not 12 " 57 "bytes\n", s, drive->name, packet_size); 58 else 59 return 1; 60 return 0; 61} 62EXPORT_SYMBOL_GPL(ide_check_atapi_device); 63 64/* PIO data transfer routine using the scatter gather table. */ 65int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, 66 unsigned int bcount, int write) 67{ 68 ide_hwif_t *hwif = drive->hwif; 69 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 70 xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data; 71 struct scatterlist *sg = pc->sg; 72 char *buf; 73 int count, done = 0; 74 75 while (bcount) { 76 count = min(sg->length - pc->b_count, bcount); 77 78 if (PageHighMem(sg_page(sg))) { 79 unsigned long flags; 80 81 local_irq_save(flags); 82 buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; 83 xf(drive, NULL, buf + pc->b_count, count); 84 kunmap_atomic(buf - sg->offset, KM_IRQ0); 85 local_irq_restore(flags); 86 } else { 87 buf = sg_virt(sg); 88 xf(drive, NULL, buf + pc->b_count, count); 89 } 90 91 bcount -= count; 92 pc->b_count += count; 93 done += count; 94 95 if (pc->b_count == sg->length) { 96 if (!--pc->sg_cnt) 97 break; 98 pc->sg = sg = sg_next(sg); 99 pc->b_count = 0; 100 } 101 } 102 103 if (bcount) { 104 printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name, 105 bcount, write ? "padding with zeros" 106 : "discarding data"); 107 ide_pad_transfer(drive, write, bcount); 108 } 109 110 return done; 111} 112EXPORT_SYMBOL_GPL(ide_io_buffers); 113 114void ide_init_pc(struct ide_atapi_pc *pc) 115{ 116 memset(pc, 0, sizeof(*pc)); 117 pc->buf = pc->pc_buf; 118 pc->buf_size = IDE_PC_BUFFER_SIZE; 119} 120EXPORT_SYMBOL_GPL(ide_init_pc); 121 122/* 123 * Generate a new packet command request in front of the request queue, before 124 * the current request, so that it will be processed immediately, on the next 125 * pass through the driver. 126 */ 127void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, 128 struct ide_atapi_pc *pc, struct request *rq) 129{ 130 blk_rq_init(NULL, rq); 131 rq->cmd_type = REQ_TYPE_SPECIAL; 132 rq->cmd_flags |= REQ_PREEMPT; 133 rq->buffer = (char *)pc; 134 rq->rq_disk = disk; 135 memcpy(rq->cmd, pc->c, 12); 136 if (drive->media == ide_tape) 137 rq->cmd[13] = REQ_IDETAPE_PC1; 138 ide_do_drive_cmd(drive, rq); 139} 140EXPORT_SYMBOL_GPL(ide_queue_pc_head); 141 142/* 143 * Add a special packet command request to the tail of the request queue, 144 * and wait for it to be serviced. 145 */ 146int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, 147 struct ide_atapi_pc *pc) 148{ 149 struct request *rq; 150 int error; 151 152 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 153 rq->cmd_type = REQ_TYPE_SPECIAL; 154 rq->buffer = (char *)pc; 155 memcpy(rq->cmd, pc->c, 12); 156 if (drive->media == ide_tape) 157 rq->cmd[13] = REQ_IDETAPE_PC1; 158 error = blk_execute_rq(drive->queue, disk, rq, 0); 159 blk_put_request(rq); 160 161 return error; 162} 163EXPORT_SYMBOL_GPL(ide_queue_pc_tail); 164 165/* TODO: unify the code thus making some arguments go away */ 166ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, 167 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, 168 void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), 169 void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), 170 int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int)) 171{ 172 ide_hwif_t *hwif = drive->hwif; 173 struct request *rq = hwif->hwgroup->rq; 174 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 175 xfer_func_t *xferfunc; 176 unsigned int temp; 177 u16 bcount; 178 u8 stat, ireason, scsi = drive->scsi; 179 180 debug_log("Enter %s - interrupt handler\n", __func__); 181 182 if (pc->flags & PC_FLAG_TIMEDOUT) { 183 drive->pc_callback(drive); 184 return ide_stopped; 185 } 186 187 /* Clear the interrupt */ 188 stat = tp_ops->read_status(hwif); 189 190 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { 191 if (hwif->dma_ops->dma_end(drive) || 192 (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) { 193 if (drive->media == ide_floppy && !scsi) 194 printk(KERN_ERR "%s: DMA %s error\n", 195 drive->name, rq_data_dir(pc->rq) 196 ? "write" : "read"); 197 pc->flags |= PC_FLAG_DMA_ERROR; 198 } else { 199 pc->xferred = pc->req_xfer; 200 if (update_buffers) 201 update_buffers(drive, pc); 202 } 203 debug_log("%s: DMA finished\n", drive->name); 204 } 205 206 /* No more interrupts */ 207 if ((stat & ATA_DRQ) == 0) { 208 debug_log("Packet command completed, %d bytes transferred\n", 209 pc->xferred); 210 211 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; 212 213 local_irq_enable_in_hardirq(); 214 215 if (drive->media == ide_tape && !scsi && 216 (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) 217 stat &= ~ATA_ERR; 218 219 if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) { 220 /* Error detected */ 221 debug_log("%s: I/O error\n", drive->name); 222 223 if (drive->media != ide_tape || scsi) { 224 pc->rq->errors++; 225 if (scsi) 226 goto cmd_finished; 227 } 228 229 if (rq->cmd[0] == REQUEST_SENSE) { 230 printk(KERN_ERR "%s: I/O error in request sense" 231 " command\n", drive->name); 232 return ide_do_reset(drive); 233 } 234 235 debug_log("[cmd %x]: check condition\n", rq->cmd[0]); 236 237 /* Retry operation */ 238 retry_pc(drive); 239 240 /* queued, but not started */ 241 return ide_stopped; 242 } 243cmd_finished: 244 pc->error = 0; 245 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && 246 (stat & ATA_DSC) == 0) { 247 dsc_handle(drive); 248 return ide_stopped; 249 } 250 251 /* Command finished - Call the callback function */ 252 drive->pc_callback(drive); 253 254 return ide_stopped; 255 } 256 257 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { 258 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; 259 printk(KERN_ERR "%s: The device wants to issue more interrupts " 260 "in DMA mode\n", drive->name); 261 ide_dma_off(drive); 262 return ide_do_reset(drive); 263 } 264 265 /* Get the number of bytes to transfer on this interrupt. */ 266 ide_read_bcount_and_ireason(drive, &bcount, &ireason); 267 268 if (ireason & ATAPI_COD) { 269 printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); 270 return ide_do_reset(drive); 271 } 272 273 if (((ireason & ATAPI_IO) == ATAPI_IO) == 274 !!(pc->flags & PC_FLAG_WRITING)) { 275 /* Hopefully, we will never get here */ 276 printk(KERN_ERR "%s: We wanted to %s, but the device wants us " 277 "to %s!\n", drive->name, 278 (ireason & ATAPI_IO) ? "Write" : "Read", 279 (ireason & ATAPI_IO) ? "Read" : "Write"); 280 return ide_do_reset(drive); 281 } 282 283 if (!(pc->flags & PC_FLAG_WRITING)) { 284 /* Reading - Check that we have enough space */ 285 temp = pc->xferred + bcount; 286 if (temp > pc->req_xfer) { 287 if (temp > pc->buf_size) { 288 printk(KERN_ERR "%s: The device wants to send " 289 "us more data than expected - " 290 "discarding data\n", 291 drive->name); 292 if (scsi) 293 temp = pc->buf_size - pc->xferred; 294 else 295 temp = 0; 296 if (temp) { 297 if (pc->sg) 298 io_buffers(drive, pc, temp, 0); 299 else 300 tp_ops->input_data(drive, NULL, 301 pc->cur_pos, temp); 302 printk(KERN_ERR "%s: transferred %d of " 303 "%d bytes\n", 304 drive->name, 305 temp, bcount); 306 } 307 pc->xferred += temp; 308 pc->cur_pos += temp; 309 ide_pad_transfer(drive, 0, bcount - temp); 310 ide_set_handler(drive, handler, timeout, 311 expiry); 312 return ide_started; 313 } 314 debug_log("The device wants to send us more data than " 315 "expected - allowing transfer\n"); 316 } 317 xferfunc = tp_ops->input_data; 318 } else 319 xferfunc = tp_ops->output_data; 320 321 if ((drive->media == ide_floppy && !scsi && !pc->buf) || 322 (drive->media == ide_tape && !scsi && pc->bh) || 323 (scsi && pc->sg)) { 324 int done = io_buffers(drive, pc, bcount, 325 !!(pc->flags & PC_FLAG_WRITING)); 326 327 /* FIXME: don't do partial completions */ 328 if (drive->media == ide_floppy && !scsi) 329 ide_end_request(drive, 1, done >> 9); 330 } else 331 xferfunc(drive, NULL, pc->cur_pos, bcount); 332 333 /* Update the current position */ 334 pc->xferred += bcount; 335 pc->cur_pos += bcount; 336 337 debug_log("[cmd %x] transferred %d bytes on that intr.\n", 338 rq->cmd[0], bcount); 339 340 /* And set the interrupt handler again */ 341 ide_set_handler(drive, handler, timeout, expiry); 342 return ide_started; 343} 344EXPORT_SYMBOL_GPL(ide_pc_intr); 345 346static u8 ide_read_ireason(ide_drive_t *drive) 347{ 348 ide_task_t task; 349 350 memset(&task, 0, sizeof(task)); 351 task.tf_flags = IDE_TFLAG_IN_NSECT; 352 353 drive->hwif->tp_ops->tf_read(drive, &task); 354 355 return task.tf.nsect & 3; 356} 357 358static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) 359{ 360 int retries = 100; 361 362 while (retries-- && ((ireason & ATAPI_COD) == 0 || 363 (ireason & ATAPI_IO))) { 364 printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " 365 "a packet command, retrying\n", drive->name); 366 udelay(100); 367 ireason = ide_read_ireason(drive); 368 if (retries == 0) { 369 printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " 370 "a packet command, ignoring\n", 371 drive->name); 372 ireason |= ATAPI_COD; 373 ireason &= ~ATAPI_IO; 374 } 375 } 376 377 return ireason; 378} 379 380ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 381 ide_handler_t *handler, unsigned int timeout, 382 ide_expiry_t *expiry) 383{ 384 ide_hwif_t *hwif = drive->hwif; 385 struct request *rq = hwif->hwgroup->rq; 386 ide_startstop_t startstop; 387 u8 ireason; 388 389 if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { 390 printk(KERN_ERR "%s: Strange, packet command initiated yet " 391 "DRQ isn't asserted\n", drive->name); 392 return startstop; 393 } 394 395 ireason = ide_read_ireason(drive); 396 if (drive->media == ide_tape && !drive->scsi) 397 ireason = ide_wait_ireason(drive, ireason); 398 399 if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { 400 printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " 401 "a packet command\n", drive->name); 402 return ide_do_reset(drive); 403 } 404 405 /* Set the interrupt routine */ 406 ide_set_handler(drive, handler, timeout, expiry); 407 408 /* Begin DMA, if necessary */ 409 if (pc->flags & PC_FLAG_DMA_OK) { 410 pc->flags |= PC_FLAG_DMA_IN_PROGRESS; 411 hwif->dma_ops->dma_start(drive); 412 } 413 414 /* Send the actual packet */ 415 if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) 416 hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12); 417 418 return ide_started; 419} 420EXPORT_SYMBOL_GPL(ide_transfer_pc); 421 422ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 423 ide_handler_t *handler, unsigned int timeout, 424 ide_expiry_t *expiry) 425{ 426 ide_hwif_t *hwif = drive->hwif; 427 u16 bcount; 428 u8 dma = 0; 429 430 /* We haven't transferred any data yet */ 431 pc->xferred = 0; 432 pc->cur_pos = pc->buf; 433 434 /* Request to transfer the entire buffer at once */ 435 if (drive->media == ide_tape && !drive->scsi) 436 bcount = pc->req_xfer; 437 else 438 bcount = min(pc->req_xfer, 63 * 1024); 439 440 if (pc->flags & PC_FLAG_DMA_ERROR) { 441 pc->flags &= ~PC_FLAG_DMA_ERROR; 442 ide_dma_off(drive); 443 } 444 445 if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { 446 if (drive->scsi) 447 hwif->sg_mapped = 1; 448 dma = !hwif->dma_ops->dma_setup(drive); 449 if (drive->scsi) 450 hwif->sg_mapped = 0; 451 } 452 453 if (!dma) 454 pc->flags &= ~PC_FLAG_DMA_OK; 455 456 ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, 457 bcount, dma); 458 459 /* Issue the packet command */ 460 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { 461 ide_execute_command(drive, ATA_CMD_PACKET, handler, 462 timeout, NULL); 463 return ide_started; 464 } else { 465 ide_execute_pkt_cmd(drive); 466 return (*handler)(drive); 467 } 468} 469EXPORT_SYMBOL_GPL(ide_issue_pc); 470