ide-atapi.c revision 0578042db3191e1ac76b53d213f2a691c3e1eaed
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 165int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) 166{ 167 struct ide_atapi_pc pc; 168 169 if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) 170 return 0; 171 172 ide_init_pc(&pc); 173 pc.c[0] = ALLOW_MEDIUM_REMOVAL; 174 pc.c[4] = on; 175 176 return ide_queue_pc_tail(drive, disk, &pc); 177} 178EXPORT_SYMBOL_GPL(ide_set_media_lock); 179 180/* TODO: unify the code thus making some arguments go away */ 181ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, 182 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, 183 void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), 184 void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), 185 int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned, int)) 186{ 187 ide_hwif_t *hwif = drive->hwif; 188 struct request *rq = hwif->hwgroup->rq; 189 const struct ide_tp_ops *tp_ops = hwif->tp_ops; 190 xfer_func_t *xferfunc; 191 unsigned int temp; 192 u16 bcount; 193 u8 stat, ireason, scsi = drive->scsi; 194 195 debug_log("Enter %s - interrupt handler\n", __func__); 196 197 if (pc->flags & PC_FLAG_TIMEDOUT) { 198 drive->pc_callback(drive); 199 return ide_stopped; 200 } 201 202 /* Clear the interrupt */ 203 stat = tp_ops->read_status(hwif); 204 205 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { 206 if (hwif->dma_ops->dma_end(drive) || 207 (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) { 208 if (drive->media == ide_floppy && !scsi) 209 printk(KERN_ERR "%s: DMA %s error\n", 210 drive->name, rq_data_dir(pc->rq) 211 ? "write" : "read"); 212 pc->flags |= PC_FLAG_DMA_ERROR; 213 } else { 214 pc->xferred = pc->req_xfer; 215 if (update_buffers) 216 update_buffers(drive, pc); 217 } 218 debug_log("%s: DMA finished\n", drive->name); 219 } 220 221 /* No more interrupts */ 222 if ((stat & ATA_DRQ) == 0) { 223 debug_log("Packet command completed, %d bytes transferred\n", 224 pc->xferred); 225 226 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; 227 228 local_irq_enable_in_hardirq(); 229 230 if (drive->media == ide_tape && !scsi && 231 (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) 232 stat &= ~ATA_ERR; 233 234 if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) { 235 /* Error detected */ 236 debug_log("%s: I/O error\n", drive->name); 237 238 if (drive->media != ide_tape || scsi) { 239 pc->rq->errors++; 240 if (scsi) 241 goto cmd_finished; 242 } 243 244 if (rq->cmd[0] == REQUEST_SENSE) { 245 printk(KERN_ERR "%s: I/O error in request sense" 246 " command\n", drive->name); 247 return ide_do_reset(drive); 248 } 249 250 debug_log("[cmd %x]: check condition\n", rq->cmd[0]); 251 252 /* Retry operation */ 253 retry_pc(drive); 254 255 /* queued, but not started */ 256 return ide_stopped; 257 } 258cmd_finished: 259 pc->error = 0; 260 if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && 261 (stat & ATA_DSC) == 0) { 262 dsc_handle(drive); 263 return ide_stopped; 264 } 265 266 /* Command finished - Call the callback function */ 267 drive->pc_callback(drive); 268 269 return ide_stopped; 270 } 271 272 if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { 273 pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; 274 printk(KERN_ERR "%s: The device wants to issue more interrupts " 275 "in DMA mode\n", drive->name); 276 ide_dma_off(drive); 277 return ide_do_reset(drive); 278 } 279 280 /* Get the number of bytes to transfer on this interrupt. */ 281 ide_read_bcount_and_ireason(drive, &bcount, &ireason); 282 283 if (ireason & ATAPI_COD) { 284 printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); 285 return ide_do_reset(drive); 286 } 287 288 if (((ireason & ATAPI_IO) == ATAPI_IO) == 289 !!(pc->flags & PC_FLAG_WRITING)) { 290 /* Hopefully, we will never get here */ 291 printk(KERN_ERR "%s: We wanted to %s, but the device wants us " 292 "to %s!\n", drive->name, 293 (ireason & ATAPI_IO) ? "Write" : "Read", 294 (ireason & ATAPI_IO) ? "Read" : "Write"); 295 return ide_do_reset(drive); 296 } 297 298 if (!(pc->flags & PC_FLAG_WRITING)) { 299 /* Reading - Check that we have enough space */ 300 temp = pc->xferred + bcount; 301 if (temp > pc->req_xfer) { 302 if (temp > pc->buf_size) { 303 printk(KERN_ERR "%s: The device wants to send " 304 "us more data than expected - " 305 "discarding data\n", 306 drive->name); 307 if (scsi) 308 temp = pc->buf_size - pc->xferred; 309 else 310 temp = 0; 311 if (temp) { 312 if (pc->sg) 313 io_buffers(drive, pc, temp, 0); 314 else 315 tp_ops->input_data(drive, NULL, 316 pc->cur_pos, temp); 317 printk(KERN_ERR "%s: transferred %d of " 318 "%d bytes\n", 319 drive->name, 320 temp, bcount); 321 } 322 pc->xferred += temp; 323 pc->cur_pos += temp; 324 ide_pad_transfer(drive, 0, bcount - temp); 325 ide_set_handler(drive, handler, timeout, 326 expiry); 327 return ide_started; 328 } 329 debug_log("The device wants to send us more data than " 330 "expected - allowing transfer\n"); 331 } 332 xferfunc = tp_ops->input_data; 333 } else 334 xferfunc = tp_ops->output_data; 335 336 if ((drive->media == ide_floppy && !scsi && !pc->buf) || 337 (drive->media == ide_tape && !scsi && pc->bh) || 338 (scsi && pc->sg)) { 339 int done = io_buffers(drive, pc, bcount, 340 !!(pc->flags & PC_FLAG_WRITING)); 341 342 /* FIXME: don't do partial completions */ 343 if (drive->media == ide_floppy && !scsi) 344 ide_end_request(drive, 1, done >> 9); 345 } else 346 xferfunc(drive, NULL, pc->cur_pos, bcount); 347 348 /* Update the current position */ 349 pc->xferred += bcount; 350 pc->cur_pos += bcount; 351 352 debug_log("[cmd %x] transferred %d bytes on that intr.\n", 353 rq->cmd[0], bcount); 354 355 /* And set the interrupt handler again */ 356 ide_set_handler(drive, handler, timeout, expiry); 357 return ide_started; 358} 359EXPORT_SYMBOL_GPL(ide_pc_intr); 360 361static u8 ide_read_ireason(ide_drive_t *drive) 362{ 363 ide_task_t task; 364 365 memset(&task, 0, sizeof(task)); 366 task.tf_flags = IDE_TFLAG_IN_NSECT; 367 368 drive->hwif->tp_ops->tf_read(drive, &task); 369 370 return task.tf.nsect & 3; 371} 372 373static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) 374{ 375 int retries = 100; 376 377 while (retries-- && ((ireason & ATAPI_COD) == 0 || 378 (ireason & ATAPI_IO))) { 379 printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " 380 "a packet command, retrying\n", drive->name); 381 udelay(100); 382 ireason = ide_read_ireason(drive); 383 if (retries == 0) { 384 printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " 385 "a packet command, ignoring\n", 386 drive->name); 387 ireason |= ATAPI_COD; 388 ireason &= ~ATAPI_IO; 389 } 390 } 391 392 return ireason; 393} 394 395ide_startstop_t ide_transfer_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 396 ide_handler_t *handler, unsigned int timeout, 397 ide_expiry_t *expiry) 398{ 399 ide_hwif_t *hwif = drive->hwif; 400 struct request *rq = hwif->hwgroup->rq; 401 ide_startstop_t startstop; 402 u8 ireason; 403 404 if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { 405 printk(KERN_ERR "%s: Strange, packet command initiated yet " 406 "DRQ isn't asserted\n", drive->name); 407 return startstop; 408 } 409 410 ireason = ide_read_ireason(drive); 411 if (drive->media == ide_tape && !drive->scsi) 412 ireason = ide_wait_ireason(drive, ireason); 413 414 if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { 415 printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " 416 "a packet command\n", drive->name); 417 return ide_do_reset(drive); 418 } 419 420 /* Set the interrupt routine */ 421 ide_set_handler(drive, handler, timeout, expiry); 422 423 /* Begin DMA, if necessary */ 424 if (pc->flags & PC_FLAG_DMA_OK) { 425 pc->flags |= PC_FLAG_DMA_IN_PROGRESS; 426 hwif->dma_ops->dma_start(drive); 427 } 428 429 /* Send the actual packet */ 430 if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) 431 hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12); 432 433 return ide_started; 434} 435EXPORT_SYMBOL_GPL(ide_transfer_pc); 436 437ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_atapi_pc *pc, 438 ide_handler_t *handler, unsigned int timeout, 439 ide_expiry_t *expiry) 440{ 441 ide_hwif_t *hwif = drive->hwif; 442 u16 bcount; 443 u8 dma = 0; 444 445 /* We haven't transferred any data yet */ 446 pc->xferred = 0; 447 pc->cur_pos = pc->buf; 448 449 /* Request to transfer the entire buffer at once */ 450 if (drive->media == ide_tape && !drive->scsi) 451 bcount = pc->req_xfer; 452 else 453 bcount = min(pc->req_xfer, 63 * 1024); 454 455 if (pc->flags & PC_FLAG_DMA_ERROR) { 456 pc->flags &= ~PC_FLAG_DMA_ERROR; 457 ide_dma_off(drive); 458 } 459 460 if ((pc->flags & PC_FLAG_DMA_OK) && drive->using_dma) { 461 if (drive->scsi) 462 hwif->sg_mapped = 1; 463 dma = !hwif->dma_ops->dma_setup(drive); 464 if (drive->scsi) 465 hwif->sg_mapped = 0; 466 } 467 468 if (!dma) 469 pc->flags &= ~PC_FLAG_DMA_OK; 470 471 ide_pktcmd_tf_load(drive, drive->scsi ? 0 : IDE_TFLAG_OUT_DEVICE, 472 bcount, dma); 473 474 /* Issue the packet command */ 475 if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { 476 ide_execute_command(drive, ATA_CMD_PACKET, handler, 477 timeout, NULL); 478 return ide_started; 479 } else { 480 ide_execute_pkt_cmd(drive); 481 return (*handler)(drive); 482 } 483} 484EXPORT_SYMBOL_GPL(ide_issue_pc); 485