ide-atapi.c 15.8 KB
Newer Older
1 2 3 4 5
/*
 * ATAPI support.
 */

#include <linux/kernel.h>
6
#include <linux/cdrom.h>
7 8
#include <linux/delay.h>
#include <linux/ide.h>
9 10 11 12 13 14 15 16 17
#include <scsi/scsi.h>

#ifdef DEBUG
#define debug_log(fmt, args...) \
	printk(KERN_INFO "ide: " fmt, ## args)
#else
#define debug_log(fmt, args...) do {} while (0)
#endif

18 19
#define ATAPI_MIN_CDB_BYTES	12

20 21
static inline int dev_is_idecd(ide_drive_t *drive)
{
22
	return drive->media == ide_cdrom || drive->media == ide_optical;
23 24
}

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/*
 * Check whether we can support a device,
 * based on the ATAPI IDENTIFY command results.
 */
int ide_check_atapi_device(ide_drive_t *drive, const char *s)
{
	u16 *id = drive->id;
	u8 gcw[2], protocol, device_type, removable, drq_type, packet_size;

	*((u16 *)&gcw) = id[ATA_ID_CONFIG];

	protocol    = (gcw[1] & 0xC0) >> 6;
	device_type =  gcw[1] & 0x1F;
	removable   = (gcw[0] & 0x80) >> 7;
	drq_type    = (gcw[0] & 0x60) >> 5;
	packet_size =  gcw[0] & 0x03;

#ifdef CONFIG_PPC
	/* kludge for Apple PowerBook internal zip */
	if (drive->media == ide_floppy && device_type == 5 &&
	    !strstr((char *)&id[ATA_ID_PROD], "CD-ROM") &&
	    strstr((char *)&id[ATA_ID_PROD], "ZIP"))
		device_type = 0;
#endif

	if (protocol != 2)
		printk(KERN_ERR "%s: %s: protocol (0x%02x) is not ATAPI\n",
			s, drive->name, protocol);
	else if ((drive->media == ide_floppy && device_type != 0) ||
		 (drive->media == ide_tape && device_type != 1))
		printk(KERN_ERR "%s: %s: invalid device type (0x%02x)\n",
			s, drive->name, device_type);
	else if (removable == 0)
		printk(KERN_ERR "%s: %s: the removable flag is not set\n",
			s, drive->name);
	else if (drive->media == ide_floppy && drq_type == 3)
		printk(KERN_ERR "%s: %s: sorry, DRQ type (0x%02x) not "
			"supported\n", s, drive->name, drq_type);
	else if (packet_size != 0)
		printk(KERN_ERR "%s: %s: packet size (0x%02x) is not 12 "
			"bytes\n", s, drive->name, packet_size);
	else
		return 1;
	return 0;
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/* PIO data transfer routine using the scatter gather table. */
int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
		    unsigned int bcount, int write)
{
	ide_hwif_t *hwif = drive->hwif;
	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
	xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
	struct scatterlist *sg = pc->sg;
	char *buf;
	int count, done = 0;

	while (bcount) {
		count = min(sg->length - pc->b_count, bcount);

		if (PageHighMem(sg_page(sg))) {
			unsigned long flags;

			local_irq_save(flags);
			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
			xf(drive, NULL, buf + pc->b_count, count);
			kunmap_atomic(buf - sg->offset, KM_IRQ0);
			local_irq_restore(flags);
		} else {
			buf = sg_virt(sg);
			xf(drive, NULL, buf + pc->b_count, count);
		}

		bcount -= count;
		pc->b_count += count;
		done += count;

		if (pc->b_count == sg->length) {
			if (!--pc->sg_cnt)
				break;
			pc->sg = sg = sg_next(sg);
			pc->b_count = 0;
		}
	}

	if (bcount) {
		printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
			bcount, write ? "padding with zeros"
				      : "discarding data");
		ide_pad_transfer(drive, write, bcount);
	}

	return done;
}
EXPORT_SYMBOL_GPL(ide_io_buffers);

122 123 124 125 126 127 128 129
void ide_init_pc(struct ide_atapi_pc *pc)
{
	memset(pc, 0, sizeof(*pc));
	pc->buf = pc->pc_buf;
	pc->buf_size = IDE_PC_BUFFER_SIZE;
}
EXPORT_SYMBOL_GPL(ide_init_pc);

130 131 132 133 134
/*
 * Generate a new packet command request in front of the request queue, before
 * the current request, so that it will be processed immediately, on the next
 * pass through the driver.
 */
135 136
static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
			      struct ide_atapi_pc *pc, struct request *rq)
137 138 139 140 141 142 143 144 145 146 147 148
{
	blk_rq_init(NULL, rq);
	rq->cmd_type = REQ_TYPE_SPECIAL;
	rq->cmd_flags |= REQ_PREEMPT;
	rq->buffer = (char *)pc;
	rq->rq_disk = disk;
	memcpy(rq->cmd, pc->c, 12);
	if (drive->media == ide_tape)
		rq->cmd[13] = REQ_IDETAPE_PC1;
	ide_do_drive_cmd(drive, rq);
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
/*
 * Add a special packet command request to the tail of the request queue,
 * and wait for it to be serviced.
 */
int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
		      struct ide_atapi_pc *pc)
{
	struct request *rq;
	int error;

	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
	rq->cmd_type = REQ_TYPE_SPECIAL;
	rq->buffer = (char *)pc;
	memcpy(rq->cmd, pc->c, 12);
	if (drive->media == ide_tape)
		rq->cmd[13] = REQ_IDETAPE_PC1;
	error = blk_execute_rq(drive->queue, disk, rq, 0);
	blk_put_request(rq);

	return error;
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);

172 173 174 175 176 177 178 179 180 181 182
int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
{
	struct ide_atapi_pc pc;

	ide_init_pc(&pc);
	pc.c[0] = TEST_UNIT_READY;

	return ide_queue_pc_tail(drive, disk, &pc);
}
EXPORT_SYMBOL_GPL(ide_do_test_unit_ready);

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
{
	struct ide_atapi_pc pc;

	ide_init_pc(&pc);
	pc.c[0] = START_STOP;
	pc.c[4] = start;

	if (drive->media == ide_tape)
		pc.flags |= PC_FLAG_WAIT_FOR_DSC;

	return ide_queue_pc_tail(drive, disk, &pc);
}
EXPORT_SYMBOL_GPL(ide_do_start_stop);

198 199 200 201
int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
{
	struct ide_atapi_pc pc;

202
	if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
203 204 205 206 207 208 209 210 211 212
		return 0;

	ide_init_pc(&pc);
	pc.c[0] = ALLOW_MEDIUM_REMOVAL;
	pc.c[4] = on;

	return ide_queue_pc_tail(drive, disk, &pc);
}
EXPORT_SYMBOL_GPL(ide_set_media_lock);

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
	ide_init_pc(pc);
	pc->c[0] = REQUEST_SENSE;
	if (drive->media == ide_floppy) {
		pc->c[4] = 255;
		pc->req_xfer = 18;
	} else {
		pc->c[4] = 20;
		pc->req_xfer = 20;
	}
}
EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);

/*
 * Called when an error was detected during the last packet command.
 * We queue a request sense packet command in the head of the request list.
 */
void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
{
	struct request *rq = &drive->request_sense_rq;
	struct ide_atapi_pc *pc = &drive->request_sense_pc;

	(void)ide_read_error(drive);
	ide_create_request_sense_cmd(drive, pc);
	if (drive->media == ide_tape)
		set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
	ide_queue_pc_head(drive, disk, pc, rq);
}
EXPORT_SYMBOL_GPL(ide_retry_pc);

244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
int ide_cd_expiry(ide_drive_t *drive)
{
	struct request *rq = HWGROUP(drive)->rq;
	unsigned long wait = 0;

	debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]);

	/*
	 * Some commands are *slow* and normally take a long time to complete.
	 * Usually we can use the ATAPI "disconnect" to bypass this, but not all
	 * commands/drives support that. Let ide_timer_expiry keep polling us
	 * for these.
	 */
	switch (rq->cmd[0]) {
	case GPCMD_BLANK:
	case GPCMD_FORMAT_UNIT:
	case GPCMD_RESERVE_RZONE_TRACK:
	case GPCMD_CLOSE_TRACK:
	case GPCMD_FLUSH_CACHE:
		wait = ATAPI_WAIT_PC;
		break;
	default:
		if (!(rq->cmd_flags & REQ_QUIET))
			printk(KERN_INFO "cmd 0x%x timed out\n",
					 rq->cmd[0]);
		wait = 0;
		break;
	}
	return wait;
}
EXPORT_SYMBOL_GPL(ide_cd_expiry);

276 277 278 279 280 281 282 283 284 285 286 287
int ide_cd_get_xferlen(struct request *rq)
{
	if (blk_fs_request(rq))
		return 32768;
	else if (blk_sense_request(rq) || blk_pc_request(rq) ||
			 rq->cmd_type == REQ_TYPE_ATA_PC)
		return rq->data_len;
	else
		return 0;
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);

288 289 290 291 292 293
/*
 * This is the usual interrupt handler which will be called during a packet
 * command.  We will transfer some of the data (as requested by the drive)
 * and will re-point interrupt handler to us.
 */
static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
294
{
295
	struct ide_atapi_pc *pc = drive->pc;
296
	ide_hwif_t *hwif = drive->hwif;
297
	struct request *rq = hwif->hwgroup->rq;
298
	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
299
	xfer_func_t *xferfunc;
300
	unsigned int timeout, temp;
301
	u16 bcount;
302
	u8 stat, ireason, dsc = 0;
303 304 305

	debug_log("Enter %s - interrupt handler\n", __func__);

306 307
	timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
					       : WAIT_TAPE_CMD;
308

309
	if (pc->flags & PC_FLAG_TIMEDOUT) {
310
		drive->pc_callback(drive, 0);
311 312 313 314
		return ide_stopped;
	}

	/* Clear the interrupt */
315
	stat = tp_ops->read_status(hwif);
316 317 318

	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
		if (hwif->dma_ops->dma_end(drive) ||
319 320
		    (drive->media == ide_tape && (stat & ATA_ERR))) {
			if (drive->media == ide_floppy)
321 322 323 324 325 326
				printk(KERN_ERR "%s: DMA %s error\n",
					drive->name, rq_data_dir(pc->rq)
						     ? "write" : "read");
			pc->flags |= PC_FLAG_DMA_ERROR;
		} else {
			pc->xferred = pc->req_xfer;
327 328
			if (drive->pc_update_buffers)
				drive->pc_update_buffers(drive, pc);
329 330 331 332 333
		}
		debug_log("%s: DMA finished\n", drive->name);
	}

	/* No more interrupts */
334
	if ((stat & ATA_DRQ) == 0) {
335 336 337 338 339 340 341
		debug_log("Packet command completed, %d bytes transferred\n",
			  pc->xferred);

		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;

		local_irq_enable_in_hardirq();

342
		if (drive->media == ide_tape &&
343 344
		    (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE)
			stat &= ~ATA_ERR;
345

346
		if ((stat & ATA_ERR) || (pc->flags & PC_FLAG_DMA_ERROR)) {
347 348 349
			/* Error detected */
			debug_log("%s: I/O error\n", drive->name);

350
			if (drive->media != ide_tape)
351 352
				pc->rq->errors++;

353
			if (rq->cmd[0] == REQUEST_SENSE) {
354 355 356 357 358
				printk(KERN_ERR "%s: I/O error in request sense"
						" command\n", drive->name);
				return ide_do_reset(drive);
			}

359
			debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
360 361

			/* Retry operation */
362
			ide_retry_pc(drive, rq->rq_disk);
363

364 365 366 367
			/* queued, but not started */
			return ide_stopped;
		}
		pc->error = 0;
368 369 370

		if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
			dsc = 1;
371

372
		/* Command finished - Call the callback function */
373
		drive->pc_callback(drive, dsc);
374

375 376 377 378 379 380 381 382 383 384 385
		return ide_stopped;
	}

	if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
		pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
		printk(KERN_ERR "%s: The device wants to issue more interrupts "
				"in DMA mode\n", drive->name);
		ide_dma_off(drive);
		return ide_do_reset(drive);
	}

386 387
	/* Get the number of bytes to transfer on this interrupt. */
	ide_read_bcount_and_ireason(drive, &bcount, &ireason);
388

389
	if (ireason & ATAPI_COD) {
390 391 392
		printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
		return ide_do_reset(drive);
	}
393

394 395
	if (((ireason & ATAPI_IO) == ATAPI_IO) ==
		!!(pc->flags & PC_FLAG_WRITING)) {
396 397 398
		/* Hopefully, we will never get here */
		printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
				"to %s!\n", drive->name,
399 400
				(ireason & ATAPI_IO) ? "Write" : "Read",
				(ireason & ATAPI_IO) ? "Read" : "Write");
401 402
		return ide_do_reset(drive);
	}
403

404 405 406 407 408 409 410 411 412
	if (!(pc->flags & PC_FLAG_WRITING)) {
		/* Reading - Check that we have enough space */
		temp = pc->xferred + bcount;
		if (temp > pc->req_xfer) {
			if (temp > pc->buf_size) {
				printk(KERN_ERR "%s: The device wants to send "
						"us more data than expected - "
						"discarding data\n",
						drive->name);
413 414

				ide_pad_transfer(drive, 0, bcount);
415
				goto next_irq;
416 417 418 419
			}
			debug_log("The device wants to send us more data than "
				  "expected - allowing transfer\n");
		}
420
		xferfunc = tp_ops->input_data;
421
	} else
422
		xferfunc = tp_ops->output_data;
423

424 425
	if ((drive->media == ide_floppy && !pc->buf) ||
	    (drive->media == ide_tape && pc->bh)) {
426
		int done = drive->pc_io_buffers(drive, pc, bcount,
427 428 429
				  !!(pc->flags & PC_FLAG_WRITING));

		/* FIXME: don't do partial completions */
430
		if (drive->media == ide_floppy)
431 432
			ide_end_request(drive, 1, done >> 9);
	} else
433 434 435 436 437 438 439
		xferfunc(drive, NULL, pc->cur_pos, bcount);

	/* Update the current position */
	pc->xferred += bcount;
	pc->cur_pos += bcount;

	debug_log("[cmd %x] transferred %d bytes on that intr.\n",
440
		  rq->cmd[0], bcount);
441
next_irq:
442
	/* And set the interrupt handler again */
443
	ide_set_handler(drive, ide_pc_intr, timeout, NULL);
444 445
	return ide_started;
}
446

447 448 449 450 451 452 453
static u8 ide_read_ireason(ide_drive_t *drive)
{
	ide_task_t task;

	memset(&task, 0, sizeof(task));
	task.tf_flags = IDE_TFLAG_IN_NSECT;

454
	drive->hwif->tp_ops->tf_read(drive, &task);
455 456 457 458

	return task.tf.nsect & 3;
}

459 460 461 462
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
{
	int retries = 100;

463 464
	while (retries-- && ((ireason & ATAPI_COD) == 0 ||
		(ireason & ATAPI_IO))) {
465 466 467
		printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
				"a packet command, retrying\n", drive->name);
		udelay(100);
468
		ireason = ide_read_ireason(drive);
469 470 471 472
		if (retries == 0) {
			printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
					"a packet command, ignoring\n",
					drive->name);
473 474
			ireason |= ATAPI_COD;
			ireason &= ~ATAPI_IO;
475 476 477 478 479 480
		}
	}

	return ireason;
}

481 482 483 484 485 486 487 488 489 490
static int ide_delayed_transfer_pc(ide_drive_t *drive)
{
	/* Send the actual packet */
	drive->hwif->tp_ops->output_data(drive, NULL, drive->pc->c, 12);

	/* Timeout for the packet command */
	return WAIT_FLOPPY_CMD;
}

static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
491
{
492
	struct ide_atapi_pc *pc = drive->pc;
493
	ide_hwif_t *hwif = drive->hwif;
494
	struct request *rq = hwif->hwgroup->rq;
495 496
	ide_expiry_t *expiry;
	unsigned int timeout;
497
	int cmd_len;
498 499 500
	ide_startstop_t startstop;
	u8 ireason;

501
	if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) {
502 503 504 505 506
		printk(KERN_ERR "%s: Strange, packet command initiated yet "
				"DRQ isn't asserted\n", drive->name);
		return startstop;
	}

507 508 509 510 511
	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
		if (drive->dma)
			drive->waiting_for_dma = 1;
	}

512
	ireason = ide_read_ireason(drive);
513
	if (drive->media == ide_tape)
514 515
		ireason = ide_wait_ireason(drive, ireason);

516
	if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
517 518
		printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
				"a packet command\n", drive->name);
519

520 521 522
		return ide_do_reset(drive);
	}

523 524 525 526 527 528
	if (dev_is_idecd(drive)) {
		/* ATAPI commands get padded out to 12 bytes minimum */
		cmd_len = COMMAND_SIZE(rq->cmd[0]);
		if (cmd_len < ATAPI_MIN_CDB_BYTES)
			cmd_len = ATAPI_MIN_CDB_BYTES;

529 530
		timeout = rq->timeout;
		expiry  = ide_cd_expiry;
531
	} else {
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
		cmd_len = ATAPI_MIN_CDB_BYTES;

		/*
		 * If necessary schedule the packet transfer to occur 'timeout'
		 * miliseconds later in ide_delayed_transfer_pc() after the
		 * device says it's ready for a packet.
		 */
		if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
			timeout = drive->pc_delay;
			expiry = &ide_delayed_transfer_pc;
		} else {
			timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
							       : WAIT_TAPE_CMD;
			expiry = NULL;
		}
547 548
	}

549
	/* Set the interrupt routine */
550
	ide_set_handler(drive, ide_pc_intr, timeout, expiry);
551 552 553 554 555 556 557 558

	/* Begin DMA, if necessary */
	if (pc->flags & PC_FLAG_DMA_OK) {
		pc->flags |= PC_FLAG_DMA_IN_PROGRESS;
		hwif->dma_ops->dma_start(drive);
	}

	/* Send the actual packet */
559
	if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
560
		hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
561 562 563

	return ide_started;
}
564

565
ide_startstop_t ide_issue_pc(ide_drive_t *drive)
566
{
567
	struct ide_atapi_pc *pc;
568
	ide_hwif_t *hwif = drive->hwif;
569
	ide_expiry_t *expiry = NULL;
570
	unsigned int timeout;
571
	u32 tf_flags;
572
	u16 bcount;
573

574 575
	if (dev_is_idecd(drive)) {
		tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
576
		bcount = ide_cd_get_xferlen(hwif->hwgroup->rq);
577
		expiry = ide_cd_expiry;
578
		timeout = ATAPI_WAIT_PC;
579 580 581

		if (drive->dma)
			drive->dma = !hwif->dma_ops->dma_setup(drive);
582
	} else {
583 584 585 586 587 588
		pc = drive->pc;

		/* We haven't transferred any data yet */
		pc->xferred = 0;
		pc->cur_pos = pc->buf;

589 590 591 592
		tf_flags = IDE_TFLAG_OUT_DEVICE;
		bcount = ((drive->media == ide_tape) ?
				pc->req_xfer :
				min(pc->req_xfer, 63 * 1024));
593

594 595 596 597
		if (pc->flags & PC_FLAG_DMA_ERROR) {
			pc->flags &= ~PC_FLAG_DMA_ERROR;
			ide_dma_off(drive);
		}
598

599 600 601
		if ((pc->flags & PC_FLAG_DMA_OK) &&
		     (drive->dev_flags & IDE_DFLAG_USING_DMA))
			drive->dma = !hwif->dma_ops->dma_setup(drive);
602

603 604
		if (!drive->dma)
			pc->flags &= ~PC_FLAG_DMA_OK;
605 606 607

		timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
						       : WAIT_TAPE_CMD;
608
	}
609

610
	ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
611 612

	/* Issue the packet command */
613
	if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
614 615
		if (drive->dma)
			drive->waiting_for_dma = 0;
616
		ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
617
				    timeout, expiry);
618 619 620
		return ide_started;
	} else {
		ide_execute_pkt_cmd(drive);
621
		return ide_transfer_pc(drive);
622 623 624
	}
}
EXPORT_SYMBOL_GPL(ide_issue_pc);