- ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET);
- udelay(50);
-
- mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
- res = ATA_STAT_DRQ;
- c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
-
- if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */
- printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",
- device, c);
- err = 0xFF;
- goto AI_OUT;
- }
-
- /* write command block */
- ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2);
-
- /* ATAPI Command written wait for completition */
- udelay(5000); /* device must set bsy */
-
- mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR;
- /*
- * if no data wait for DRQ = 0 BSY = 0
- * if data wait for DRQ = 1 BSY = 0
- */
- res = 0;
- if (buflen)
- res = ATA_STAT_DRQ;
- c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
- if ((c & mask) != res) {
- if (c & ATA_STAT_ERR) {
- err = (ide_inb(device, ATA_ERROR_REG)) >> 4;
- debug("atapi_issue 1 returned sense key %X status %02X\n",
- err, c);
- } else {
- printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n",
- ccb[0], c);
- err = 0xFF;
- }
- goto AI_OUT;
- }
- n = ide_inb(device, ATA_CYL_HIGH);
- n <<= 8;
- n += ide_inb(device, ATA_CYL_LOW);
- if (n > buflen) {
- printf("ERROR, transfer bytes %d requested only %d\n", n,
- buflen);
- err = 0xff;
- goto AI_OUT;
- }
- if ((n == 0) && (buflen < 0)) {
- printf("ERROR, transfer bytes %d requested %d\n", n, buflen);
- err = 0xff;
- goto AI_OUT;
- }
- if (n != buflen) {
- debug("WARNING, transfer bytes %d not equal with requested %d\n",
- n, buflen);
- }
- if (n != 0) { /* data transfer */
- debug("ATAPI_ISSUE: %d Bytes to transfer\n", n);
- /* we transfer shorts */
- n >>= 1;
- /* ok now decide if it is an in or output */
- if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
- debug("Write to device\n");
- ide_output_data_shorts(device,
- (unsigned short *) buffer, n);
- } else {
- debug("Read from device @ %p shorts %d\n", buffer, n);
- ide_input_data_shorts(device,
- (unsigned short *) buffer, n);
- }
- }
- udelay(5000); /* seems that some CD ROMs need this... */
- mask = ATA_STAT_BUSY | ATA_STAT_ERR;
- res = 0;
- c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res);
- if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
- err = (ide_inb(device, ATA_ERROR_REG) >> 4);
- debug("atapi_issue 2 returned sense key %X status %X\n", err,
- c);
- } else {
- err = 0;