Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=94f5a86dc37c66b9ec0d7426a7518740fa41d871
Commit:     94f5a86dc37c66b9ec0d7426a7518740fa41d871
Parent:     64814f2399e7dd1e6e53dd7d08a4ad54d02665d3
Author:     Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
AuthorDate: Fri Feb 1 23:09:26 2008 +0100
Committer:  Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
CommitDate: Fri Feb 1 23:09:26 2008 +0100

    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 <[EMAIL PROTECTED]>
---
 drivers/ide/ide-cd.c |  207 +++++++++++++++++---------------------------------
 1 files changed, 69 insertions(+), 138 deletions(-)

diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2e0c933..5839761 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)
 }
 
 /*
- * Interrupt routine.  Called when a read request has completed.
- */
-static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
-{
-       int stat;
-       int ireason, len, sectors_to_transfer, nskip;
-       struct cdrom_info *info = drive->driver_data;
-       u8 lowcyl = 0, highcyl = 0;
-       int dma = info->dma, dma_error = 0;
-
-       struct request *rq = HWGROUP(drive)->rq;
-
-       /*
-        * handle dma case
-        */
-       if (dma) {
-               info->dma = 0;
-               dma_error = HWIF(drive)->ide_dma_end(drive);
-               if (dma_error) {
-                       printk(KERN_ERR "%s: DMA read error\n", drive->name);
-                       ide_dma_off(drive);
-               }
-       }
-
-       if (cdrom_decode_status(drive, 0, &stat))
-               return ide_stopped;
-
-       if (dma) {
-               if (!dma_error) {
-                       ide_end_request(drive, 1, rq->nr_sectors);
-                       return ide_stopped;
-               } else
-                       return ide_error(drive, "dma error", stat);
-       }
-
-       /* Read the interrupt reason and the transfer length. */
-       ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
-       lowcyl  = HWIF(drive)->INB(IDE_BCOUNTL_REG);
-       highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
-
-       len = lowcyl + (256 * highcyl);
-
-       /* If DRQ is clear, the command has completed. */
-       if ((stat & DRQ_STAT) == 0) {
-               /* If we're not done filling the current buffer, complain.
-                  Otherwise, complete the command normally. */
-               if (rq->current_nr_sectors > 0) {
-                       printk (KERN_ERR "%s: cdrom_read_intr: data underrun 
(%d blocks)\n",
-                               drive->name, rq->current_nr_sectors);
-                       rq->cmd_flags |= REQ_FAILED;
-                       cdrom_end_request(drive, 0);
-               } else
-                       cdrom_end_request(drive, 1);
-               return ide_stopped;
-       }
-
-       /* Check that the drive is expecting to do the same thing we are. */
-       if (cdrom_read_check_ireason (drive, len, ireason))
-               return ide_stopped;
-
-       if (ide_cd_check_transfer_size(drive, len)) {
-               cdrom_end_request(drive, 0);
-               return ide_stopped;
-       }
-
-       /* The number of sectors we need to read from the drive. */
-       sectors_to_transfer = len / SECTOR_SIZE;
-
-       /* First, figure out if we need to bit-bucket
-          any of the leading sectors. */
-       nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), 
sectors_to_transfer);
-
-       if (nskip > 0) {
-               ide_cd_drain_data(drive, nskip);
-               rq->current_nr_sectors -= nskip;
-               sectors_to_transfer -= nskip;
-       }
-
-       /* Now loop while we still have data to read from the drive. */
-       while (sectors_to_transfer > 0) {
-               int this_transfer;
-
-               /* If we've filled the present buffer but there's another
-                  chained buffer after it, move on. */
-               if (rq->current_nr_sectors == 0 && rq->nr_sectors)
-                       cdrom_end_request(drive, 1);
-
-               /* If the buffers are full, cache the rest of the data in our
-                  internal buffer. */
-               if (rq->current_nr_sectors == 0) {
-                       cdrom_buffer_sectors(drive, rq->sector, 
sectors_to_transfer);
-                       sectors_to_transfer = 0;
-               } else {
-                       /* Transfer data to the buffers.
-                          Figure out how many sectors we can transfer
-                          to the current buffer. */
-                       this_transfer = min_t(int, sectors_to_transfer,
-                                            rq->current_nr_sectors);
-
-                       /* Read this_transfer sectors
-                          into the current buffer. */
-                       while (this_transfer > 0) {
-                               HWIF(drive)->atapi_input_bytes(drive, 
rq->buffer, SECTOR_SIZE);
-                               rq->buffer += SECTOR_SIZE;
-                               --rq->nr_sectors;
-                               --rq->current_nr_sectors;
-                               ++rq->sector;
-                               --this_transfer;
-                               --sectors_to_transfer;
-                       }
-               }
-       }
-
-       /* Done moving data!  Wait for another interrupt. */
-       ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
-       return ide_started;
-}
-
-/*
  * Try to satisfy some of the current read request from our cached data.
  * Returns nonzero if the request has been completed, zero otherwise.
  */
@@ -916,6 +797,8 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
        return 0;
 }
 
+static ide_startstop_t cdrom_rw_intr(ide_drive_t *);
+
 /*
  * Routine to send a read packet command to the drive.
  * 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)
        rq->timeout = ATAPI_WAIT_PC;
 
        /* Send the command to the drive and return. */
-       return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr);
+       return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr);
 }
 
 
@@ -1168,7 +1051,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
 /*
  * best way to deal with dma that is not sector aligned right now... note
  * that in this path we are not using ->data or ->buffer at all. this irs
- * can replace cdrom_read_intr() and cdrom_write_intr() in the future.
+ * can replace cdrom_rw_intr() in the future.
  */
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 {
@@ -1343,21 +1226,22 @@ end_request:
        return ide_stopped;
 }
 
-static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
+static ide_startstop_t cdrom_rw_intr(ide_drive_t *drive)
 {
-       int stat, ireason, len, sectors_to_transfer, uptodate;
        struct cdrom_info *info = drive->driver_data;
-       int dma_error = 0, dma = info->dma;
-       u8 lowcyl = 0, highcyl = 0;
-
        struct request *rq = HWGROUP(drive)->rq;
+       xfer_func_t *xferfunc;
+       int stat, ireason, len, sectors_to_transfer, uptodate, nskip;
+       int dma_error = 0, dma = info->dma, write = rq_data_dir(rq) == WRITE;
+       u8 lowcyl = 0, highcyl = 0;
 
        /* Check for errors. */
        if (dma) {
                info->dma = 0;
                dma_error = HWIF(drive)->ide_dma_end(drive);
                if (dma_error) {
-                       printk(KERN_ERR "%s: DMA write error\n", drive->name);
+                       printk(KERN_ERR "%s: DMA %s error\n", drive->name,
+                                       write ? "write" : "read");
                        ide_dma_off(drive);
                }
        }
@@ -1385,7 +1269,8 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t 
*drive)
 
        /* If DRQ is clear, the command has completed. */
        if ((stat & DRQ_STAT) == 0) {
-               /* If we're not done writing, complain.
+               /*
+                * If we're not done reading/writing, complain.
                 * Otherwise, complete the command normally.
                 */
                uptodate = 1;
@@ -1393,27 +1278,73 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t 
*drive)
                        printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
                                        drive->name, __FUNCTION__,
                                        rq->current_nr_sectors);
+                       if (!write)
+                               rq->cmd_flags |= REQ_FAILED;
                        uptodate = 0;
                }
                cdrom_end_request(drive, uptodate);
                return ide_stopped;
        }
 
+       sectors_to_transfer = len / SECTOR_SIZE;
+
        /* Check that the drive is expecting to do the same thing we are. */
-       if (cdrom_write_check_ireason(drive, len, ireason))
-               return ide_stopped;
+       if (write) {
+               if (cdrom_write_check_ireason(drive, len, ireason))
+                       return ide_stopped;
 
-       sectors_to_transfer = len / SECTOR_SIZE;
+               xferfunc = HWIF(drive)->atapi_output_bytes;
+       } else {
+               if (cdrom_read_check_ireason(drive, len, ireason))
+                       return ide_stopped;
+
+               if (ide_cd_check_transfer_size(drive, len)) {
+                       cdrom_end_request(drive, 0);
+                       return ide_stopped;
+               }
+
+               /*
+                * First, figure out if we need to bit-bucket
+                * any of the leading sectors.
+                */
+               nskip = min_t(int, rq->current_nr_sectors
+                                  - bio_cur_sectors(rq->bio),
+                                  sectors_to_transfer);
+
+               if (nskip > 0) {
+                       ide_cd_drain_data(drive, nskip);
+                       rq->current_nr_sectors -= nskip;
+                       sectors_to_transfer -= nskip;
+               }
+
+               xferfunc = HWIF(drive)->atapi_input_bytes;
+       }
 
        /*
-        * now loop and write out the data
+        * now loop and read/write the data
         */
        while (sectors_to_transfer > 0) {
                int this_transfer;
 
+               /*
+                * If we've filled the present buffer but there's another
+                * chained buffer after it, move on.
+                */
+               if (!write && rq->current_nr_sectors == 0 && rq->nr_sectors)
+                       cdrom_end_request(drive, 1);
+
                if (!rq->current_nr_sectors) {
-                       printk(KERN_ERR "%s: %s: confused, missing data\n",
-                                       drive->name, __FUNCTION__);
+                       if (!write)
+                               /*
+                                * If the buffers are full, cache the rest
+                                * of the data in our internal buffer.
+                                */
+                               cdrom_buffer_sectors(drive, rq->sector,
+                                                    sectors_to_transfer);
+                       else
+                               printk(KERN_ERR "%s: %s: confused, missing "
+                                               "data\n",
+                                               drive->name, __FUNCTION__);
                        break;
                }
 
@@ -1423,7 +1354,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t 
*drive)
                this_transfer = min_t(int, sectors_to_transfer, 
rq->current_nr_sectors);
 
                while (this_transfer > 0) {
-                       HWIF(drive)->atapi_output_bytes(drive, rq->buffer, 
SECTOR_SIZE);
+                       xferfunc(drive, rq->buffer, SECTOR_SIZE);
                        rq->buffer += SECTOR_SIZE;
                        --rq->nr_sectors;
                        --rq->current_nr_sectors;
@@ -1435,12 +1366,12 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t 
*drive)
                /*
                 * current buffer complete, move on
                 */
-               if (rq->current_nr_sectors == 0 && rq->nr_sectors)
+               if (write && rq->current_nr_sectors == 0 && rq->nr_sectors)
                        cdrom_end_request(drive, 1);
        }
 
        /* re-arm handler */
-       ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
+       ide_set_handler(drive, cdrom_rw_intr, ATAPI_WAIT_PC, NULL);
        return ide_started;
 }
 
@@ -1453,7 +1384,7 @@ static ide_startstop_t cdrom_start_write_cont(ide_drive_t 
*drive)
 #endif
        rq->timeout = ATAPI_WAIT_PC;
 
-       return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
+       return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr);
 }
 
 static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request 
*rq)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to