aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-02-01 17:09:26 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-02-01 17:09:26 -0500
commit94f5a86dc37c66b9ec0d7426a7518740fa41d871 (patch)
tree09cf08464f56f5b36115e583a0cc0e6b9b33545f /drivers/ide/ide-cd.c
parent64814f2399e7dd1e6e53dd7d08a4ad54d02665d3 (diff)
ide-cd: merge cdrom_read_intr() and cdrom_write_intr()
Add handling of read requests to cdrom_write_intr(), rename it to cdrom_rw_intr() and remove no longer needed cdrom_read_intr(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c207
1 files changed, 69 insertions, 138 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2e0c93377582..58397617b281 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -739,125 +739,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
739} 739}
740 740
741/* 741/*
742 * Interrupt routine. Called when a read request has completed.
743 */
744static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
745{
746 int stat;
747 int ireason, len, sectors_to_transfer, nskip;
748 struct cdrom_info *info = drive->driver_data;
749 u8 lowcyl = 0, highcyl = 0;
750 int dma = info->dma, dma_error = 0;
751
752 struct request *rq = HWGROUP(drive)->rq;
753
754 /*
755 * handle dma case
756 */
757 if (dma) {
758 info->dma = 0;
759 dma_error = HWIF(drive)->ide_dma_end(drive);
760 if (dma_error) {
761 printk(KERN_ERR "%s: DMA read error\n", drive->name);
762 ide_dma_off(drive);
763 }
764 }
765
766 if (cdrom_decode_status(drive, 0, &stat))
767 return ide_stopped;
768
769 if (dma) {
770 if (!dma_error) {
771 ide_end_request(drive, 1, rq->nr_sectors);
772 return ide_stopped;
773 } else
774 return ide_error(drive, "dma error", stat);
775 }
776
777 /* Read the interrupt reason and the transfer length. */
778 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
779 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
780 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
781
782 len = lowcyl + (256 * highcyl);
783
784 /* If DRQ is clear, the command has completed. */
785 if ((stat & DRQ_STAT) == 0) {
786 /* If we're not done filling the current buffer, complain.
787 Otherwise, complete the command normally. */
788 if (rq->current_nr_sectors > 0) {
789 printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
790 drive->name, rq->current_nr_sectors);
791 rq->cmd_flags |= REQ_FAILED;
792 cdrom_end_request(drive, 0);
793 } else
794 cdrom_end_request(drive, 1);
795 return ide_stopped;
796 }
797
798 /* Check that the drive is expecting to do the same thing we are. */
799 if (cdrom_read_check_ireason (drive, len, ireason))
800 return ide_stopped;
801
802 if (ide_cd_check_transfer_size(drive, len)) {
803 cdrom_end_request(drive, 0);
804 return ide_stopped;
805 }
806
807 /* The number of sectors we need to read from the drive. */
808 sectors_to_transfer = len / SECTOR_SIZE;
809
810 /* First, figure out if we need to bit-bucket
811 any of the leading sectors. */
812 nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer);
813
814 if (nskip > 0) {
815 ide_cd_drain_data(drive, nskip);
816 rq->current_nr_sectors -= nskip;
817 sectors_to_transfer -= nskip;
818 }
819
820 /* Now loop while we still have data to read from the drive. */
821 while (sectors_to_transfer > 0) {
822 int this_transfer;
823
824 /* If we've filled the present buffer but there's another
825 chained buffer after it, move on. */
826 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
827 cdrom_end_request(drive, 1);
828
829 /* If the buffers are full, cache the rest of the data in our
830 internal buffer. */
831 if (rq->current_nr_sectors == 0) {
832 cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer);
833 sectors_to_transfer = 0;
834 } else {
835 /* Transfer data to the buffers.
836 Figure out how many sectors we can transfer
837 to the current buffer. */
838 this_transfer = min_t(int, sectors_to_transfer,
839 rq->current_nr_sectors);
840
841 /* Read this_transfer sectors
842 into the current buffer. */
843 while (this_transfer > 0) {
844 HWIF(drive)->atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE);
845 rq->buffer += SECTOR_SIZE;
846 --rq->nr_sectors;
847 --rq->current_nr_sectors;
848 ++rq->sector;
849 --this_transfer;
850 --sectors_to_transfer;
851 }
852 }
853 }
854
855 /* Done moving data! Wait for another interrupt. */
856 ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
857 return ide_started;
858}
859
860/*
861 * Try to satisfy some of the current read request from our cached data. 742 * Try to satisfy some of the current read request from our cached data.
862 * Returns nonzero if the request has been completed, zero otherwise. 743 * Returns nonzero if the request has been completed, zero otherwise.
863 */ 744 */
@@ -916,6 +797,8 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
916 return 0; 797 return 0;
917} 798}
918 799
800static ide_startstop_t cdrom_rw_intr(ide_drive_t *);
801
919/* 802/*
920 * Routine to send a read packet command to the drive. 803 * Routine to send a read packet command to the drive.
921 * This is usually called directly from cdrom_start_read. 804 * This is usually called directly from cdrom_start_read.
@@ -954,7 +837,7 @@ static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
954 rq->timeout = ATAPI_WAIT_PC; 837 rq->timeout = ATAPI_WAIT_PC;
955 838
956 /* Send the command to the drive and return. */ 839 /* Send the command to the drive and return. */
957 return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr); 840 return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr);
958} 841}
959 842
960 843
@@ -1168,7 +1051,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
1168/* 1051/*
1169 * best way to deal with dma that is not sector aligned right now... note 1052 * best way to deal with dma that is not sector aligned right now... note
1170 * that in this path we are not using ->data or ->buffer at all. this irs 1053 * that in this path we are not using ->data or ->buffer at all. this irs
1171 * can replace cdrom_read_intr() and cdrom_write_intr() in the future. 1054 * can replace cdrom_rw_intr() in the future.
1172 */ 1055 */
1173static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) 1056static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1174{ 1057{
@@ -1343,21 +1226,22 @@ end_request:
1343 return ide_stopped; 1226 return ide_stopped;
1344} 1227}
1345 1228
1346static ide_startstop_t cdrom_write_intr(ide_drive_t *drive) 1229static ide_startstop_t cdrom_rw_intr(ide_drive_t *drive)
1347{ 1230{
1348 int stat, ireason, len, sectors_to_transfer, uptodate;
1349 struct cdrom_info *info = drive->driver_data; 1231 struct cdrom_info *info = drive->driver_data;
1350 int dma_error = 0, dma = info->dma;
1351 u8 lowcyl = 0, highcyl = 0;
1352
1353 struct request *rq = HWGROUP(drive)->rq; 1232 struct request *rq = HWGROUP(drive)->rq;
1233 xfer_func_t *xferfunc;
1234 int stat, ireason, len, sectors_to_transfer, uptodate, nskip;
1235 int dma_error = 0, dma = info->dma, write = rq_data_dir(rq) == WRITE;
1236 u8 lowcyl = 0, highcyl = 0;
1354 1237
1355 /* Check for errors. */ 1238 /* Check for errors. */
1356 if (dma) { 1239 if (dma) {
1357 info->dma = 0; 1240 info->dma = 0;
1358 dma_error = HWIF(drive)->ide_dma_end(drive); 1241 dma_error = HWIF(drive)->ide_dma_end(drive);
1359 if (dma_error) { 1242 if (dma_error) {
1360 printk(KERN_ERR "%s: DMA write error\n", drive->name); 1243 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
1244 write ? "write" : "read");
1361 ide_dma_off(drive); 1245 ide_dma_off(drive);
1362 } 1246 }
1363 } 1247 }
@@ -1385,7 +1269,8 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1385 1269
1386 /* If DRQ is clear, the command has completed. */ 1270 /* If DRQ is clear, the command has completed. */
1387 if ((stat & DRQ_STAT) == 0) { 1271 if ((stat & DRQ_STAT) == 0) {
1388 /* If we're not done writing, complain. 1272 /*
1273 * If we're not done reading/writing, complain.
1389 * Otherwise, complete the command normally. 1274 * Otherwise, complete the command normally.
1390 */ 1275 */
1391 uptodate = 1; 1276 uptodate = 1;
@@ -1393,27 +1278,73 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1393 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n", 1278 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
1394 drive->name, __FUNCTION__, 1279 drive->name, __FUNCTION__,
1395 rq->current_nr_sectors); 1280 rq->current_nr_sectors);
1281 if (!write)
1282 rq->cmd_flags |= REQ_FAILED;
1396 uptodate = 0; 1283 uptodate = 0;
1397 } 1284 }
1398 cdrom_end_request(drive, uptodate); 1285 cdrom_end_request(drive, uptodate);
1399 return ide_stopped; 1286 return ide_stopped;
1400 } 1287 }
1401 1288
1289 sectors_to_transfer = len / SECTOR_SIZE;
1290
1402 /* Check that the drive is expecting to do the same thing we are. */ 1291 /* Check that the drive is expecting to do the same thing we are. */
1403 if (cdrom_write_check_ireason(drive, len, ireason)) 1292 if (write) {
1404 return ide_stopped; 1293 if (cdrom_write_check_ireason(drive, len, ireason))
1294 return ide_stopped;
1405 1295
1406 sectors_to_transfer = len / SECTOR_SIZE; 1296 xferfunc = HWIF(drive)->atapi_output_bytes;
1297 } else {
1298 if (cdrom_read_check_ireason(drive, len, ireason))
1299 return ide_stopped;
1300
1301 if (ide_cd_check_transfer_size(drive, len)) {
1302 cdrom_end_request(drive, 0);
1303 return ide_stopped;
1304 }
1305
1306 /*
1307 * First, figure out if we need to bit-bucket
1308 * any of the leading sectors.
1309 */
1310 nskip = min_t(int, rq->current_nr_sectors
1311 - bio_cur_sectors(rq->bio),
1312 sectors_to_transfer);
1313
1314 if (nskip > 0) {
1315 ide_cd_drain_data(drive, nskip);
1316 rq->current_nr_sectors -= nskip;
1317 sectors_to_transfer -= nskip;
1318 }
1319
1320 xferfunc = HWIF(drive)->atapi_input_bytes;
1321 }
1407 1322
1408 /* 1323 /*
1409 * now loop and write out the data 1324 * now loop and read/write the data
1410 */ 1325 */
1411 while (sectors_to_transfer > 0) { 1326 while (sectors_to_transfer > 0) {
1412 int this_transfer; 1327 int this_transfer;
1413 1328
1329 /*
1330 * If we've filled the present buffer but there's another
1331 * chained buffer after it, move on.
1332 */
1333 if (!write && rq->current_nr_sectors == 0 && rq->nr_sectors)
1334 cdrom_end_request(drive, 1);
1335
1414 if (!rq->current_nr_sectors) { 1336 if (!rq->current_nr_sectors) {
1415 printk(KERN_ERR "%s: %s: confused, missing data\n", 1337 if (!write)
1416 drive->name, __FUNCTION__); 1338 /*
1339 * If the buffers are full, cache the rest
1340 * of the data in our internal buffer.
1341 */
1342 cdrom_buffer_sectors(drive, rq->sector,
1343 sectors_to_transfer);
1344 else
1345 printk(KERN_ERR "%s: %s: confused, missing "
1346 "data\n",
1347 drive->name, __FUNCTION__);
1417 break; 1348 break;
1418 } 1349 }
1419 1350
@@ -1423,7 +1354,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1423 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors); 1354 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors);
1424 1355
1425 while (this_transfer > 0) { 1356 while (this_transfer > 0) {
1426 HWIF(drive)->atapi_output_bytes(drive, rq->buffer, SECTOR_SIZE); 1357 xferfunc(drive, rq->buffer, SECTOR_SIZE);
1427 rq->buffer += SECTOR_SIZE; 1358 rq->buffer += SECTOR_SIZE;
1428 --rq->nr_sectors; 1359 --rq->nr_sectors;
1429 --rq->current_nr_sectors; 1360 --rq->current_nr_sectors;
@@ -1435,12 +1366,12 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1435 /* 1366 /*
1436 * current buffer complete, move on 1367 * current buffer complete, move on
1437 */ 1368 */
1438 if (rq->current_nr_sectors == 0 && rq->nr_sectors) 1369 if (write && rq->current_nr_sectors == 0 && rq->nr_sectors)
1439 cdrom_end_request(drive, 1); 1370 cdrom_end_request(drive, 1);
1440 } 1371 }
1441 1372
1442 /* re-arm handler */ 1373 /* re-arm handler */
1443 ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL); 1374 ide_set_handler(drive, cdrom_rw_intr, ATAPI_WAIT_PC, NULL);
1444 return ide_started; 1375 return ide_started;
1445} 1376}
1446 1377
@@ -1453,7 +1384,7 @@ static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
1453#endif 1384#endif
1454 rq->timeout = ATAPI_WAIT_PC; 1385 rq->timeout = ATAPI_WAIT_PC;
1455 1386
1456 return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr); 1387 return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr);
1457} 1388}
1458 1389
1459static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) 1390static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)