patch-2.3.26 linux/drivers/block/ide-cd.c

Next file: linux/drivers/block/ide-disk.c
Previous file: linux/drivers/block/icside.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
@@ -24,11 +24,6 @@
  *
  * ----------------------------------
  * TO DO LIST:
- * -Implement Microsoft Media Status Notification per the spec at
- *   http://www.microsoft.com/hwdev/respec/storspec.htm
- *   This will allow us to get automagically notified when the media changes
- *   on ATAPI drives (something the stock ATAPI spec is lacking).  Looks
- *   very cool.  I discovered its existance the other day at work...
  * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
  *   boot
  *
@@ -537,6 +532,7 @@
 	}
 	if (rq->cmd == READ && !rq->current_nr_sectors)
 		uptodate = 1;
+
 	ide_end_request (uptodate, HWGROUP(drive));
 }
 
@@ -663,6 +659,21 @@
 	return 1;
 }
 
+static int cdrom_timer_expiry(ide_drive_t *drive)
+{
+	struct request *rq = HWGROUP(drive)->rq;
+	struct packet_command *pc = (struct packet_command *) rq->buffer;
+	unsigned long wait = 0;
+
+	printk("in expiry\n");
+	/* blank and format can take an extremly long time to
+	 * complete, if the IMMED bit was not set.
+	 */
+	if (pc->c[0] == GPCMD_BLANK || pc->c[0] == GPCMD_FORMAT_UNIT)
+		wait = 60*60*HZ;
+
+	return wait;
+}
 
 /* Set up the device registers for transferring a packet command on DEV,
    expecting to later transfer XFERLEN bytes.  HANDLER is the routine
@@ -696,7 +707,7 @@
 		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
-		ide_set_handler (drive, handler);
+		ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
@@ -706,7 +717,6 @@
 	return 0;
 }
 
-
 /* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
    The device registers must have already been prepared
    by cdrom_start_packet_command.
@@ -716,11 +726,6 @@
                                           unsigned char *cmd_buf, int cmd_len,
 					  ide_handler_t *handler)
 {
-	/* don't timeout for blank and format commands. they may take
-	 * a _very_ long time. */
-	if (cmd_buf[0] == GPCMD_BLANK || cmd_buf[0] == GPCMD_FORMAT_UNIT)
-		drive->timeout = 0;
-
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
 		/* Here we should have been called after receiving an interrupt
 		   from the device.  DRQ should how be set. */
@@ -736,7 +741,7 @@
 	}
 
 	/* Arm the interrupt handler. */
-	ide_set_handler (drive, handler);
+	ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
 
 	/* Send the command to the device. */
 	atapi_output_bytes (drive, cmd_buf, cmd_len);
@@ -769,17 +774,9 @@
 
 	char *dest;
 
-	/* If we don't yet have a sector buffer, try to allocate one.
-	   If we can't get one atomically, it's not fatal -- we'll just throw
-	   the data away rather than caching it. */
-	if (info->buffer == NULL) {
-		info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_ATOMIC);
-
-		/* If we couldn't get a buffer,
-		   don't try to buffer anything... */
-		if (info->buffer == NULL)
+	/* If we couldn't get a buffer, don't try to buffer anything... */
+	if (info->buffer == NULL)
 			sectors_to_buffer = 0;
-	}
 
 	/* If this is the first sector in the buffer, remember its number. */
 	if (info->nsectors_buffered == 0)
@@ -866,13 +863,14 @@
 		return;
  
 	if (dma) {
-		if (!dma_error) {
-			for (i = rq->nr_sectors; i > 0;) {
-				i -= rq->current_nr_sectors;
-				ide_end_request(1, HWGROUP(drive));
-			}
-		} else
+		if (dma_error) {
 			ide_error (drive, "dma error", stat);
+			return;
+		}
+		for (i = rq->nr_sectors; i > 0;) {
+			i -= rq->current_nr_sectors;
+			ide_end_request(1, HWGROUP(drive));
+		}
 		return;
 	}
 
@@ -968,7 +966,7 @@
 
 	/* Done moving data!
 	   Wait for another interrupt. */
-	ide_set_handler(drive, &cdrom_read_intr);
+	ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
 }
 
 /*
@@ -1206,9 +1204,6 @@
 	struct request *rq = HWGROUP(drive)->rq;
 	struct packet_command *pc = (struct packet_command *)rq->buffer;
 
-	/* restore timeout after blank or format command */
-	drive->timeout = WAIT_CMD;
-
 	/* Check for errors. */
 	if (cdrom_decode_status (drive, 0, &stat))
 		return;
@@ -1294,7 +1289,7 @@
 	}
 
 	/* Now we wait for another interrupt. */
-	ide_set_handler (drive, &cdrom_pc_intr);
+	ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 }
 
 
@@ -1789,7 +1784,7 @@
 
 	/* Now try to get the total cdrom capacity. */
 #if 0
-	stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor,
+	stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
 				     (long *)&toc->capacity);
 	if (stat)
 #endif
@@ -1797,6 +1792,7 @@
 	if (stat) toc->capacity = 0x1fffff;
 
 	/* for general /dev/cdrom like mounting, one big disc */
+	drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
 	HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >>
 					(BLOCK_SIZE_BITS - 9);
 
@@ -1812,11 +1808,11 @@
 	i = toc->hdr.first_track;
 	while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) {
 		drive->part[minor & PARTN_MASK].start_sect = 0;
- 		drive->part[minor & PARTN_MASK].nr_sects = (toc->ent[i].addr.lba *
+ 		drive->part[minor & PARTN_MASK].nr_sects =
+			(toc->ent[i].addr.lba *
 			SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9);
 		HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba *
 			SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
-		blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
 		i++;
 		minor++;
 	}
@@ -2273,8 +2269,11 @@
 		struct atapi_capabilities_page cap;
 	} buf;
 
-	if (CDROM_CONFIG_FLAGS (drive)->nec260)
+	if (CDROM_CONFIG_FLAGS (drive)->nec260) {
+		CDROM_CONFIG_FLAGS (drive)->no_eject = 0;                       
+		CDROM_CONFIG_FLAGS (drive)->audio_play = 1;       
 		return nslots;
+	}
 
 	init_cdrom_command(&cgc, &buf, sizeof(buf));
 	/* we have to cheat a little here. the packet will eventually
@@ -2342,9 +2341,12 @@
 			(ntohs(buf.cap.maxspeed) + (176/2)) / 176;
 	}
 
-	printk ("%s: ATAPI %dX %s", 
-        	drive->name, CDROM_CONFIG_FLAGS (drive)->max_speed,
-		(CDROM_CONFIG_FLAGS (drive)->dvd) ? "DVD-ROM" : "CD-ROM");
+	/* don't print speed if the drive reported 0.
+	 */
+	printk("%s: ATAPI", drive->name);
+	if (CDROM_CONFIG_FLAGS(drive)->max_speed)
+		printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
+	printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
 
 	if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_ram)
         	printk (" DVD%s%s", 
@@ -2398,11 +2400,10 @@
 	int nslots;
 
 	set_device_ro(MKDEV(HWIF(drive)->major, minor), 1);
-	blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
+	set_blocksize(MKDEV(HWIF(drive)->major, minor), CD_FRAMESIZE);
 
 	drive->special.all	= 0;
 	drive->ready_stat	= 0;
-	drive->timeout		= WAIT_CMD;
 
 	CDROM_STATE_FLAGS (drive)->media_changed = 1;
 	CDROM_STATE_FLAGS (drive)->toc_valid     = 0;
@@ -2435,10 +2436,14 @@
 	/* limit transfer size per interrupt. */
 	CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
 	if (drive->id != NULL) {
+		/* a testament to the nice quality of Samsung drives... */
 		if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
 			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
 		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
 			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
+		/* the 3231 model does not support the SET_CD_SPEED command */
+		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
+			cdi->mask |= CDC_SELECT_SPEED;
 	}
 
 #if ! STANDARD_ATAPI
@@ -2534,9 +2539,12 @@
 static
 int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
 {
+	struct cdrom_info *info = drive->driver_data;
 	int rc;
 
 	MOD_INC_USE_COUNT;
+	if (info->buffer == NULL)
+		info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
 	rc = cdrom_fops.open (ip, fp);
 	if (rc) {
 		drive->usage--;
@@ -2617,12 +2625,7 @@
 MODULE_PARM(ignore, "s");
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
-int init_module (void)
-{
-	return ide_cdrom_init();
-}
-
-void cleanup_module(void)
+void __exit ide_cdrom_exit(void)
 {
 	ide_drive_t *drive;
 	int failed = 0;
@@ -2636,7 +2639,7 @@
 }
 #endif /* MODULE */
  
-int ide_cdrom_init (void)
+int __init ide_cdrom_init (void)
 {
 	ide_drive_t *drive;
 	struct cdrom_info *info;
@@ -2677,3 +2680,6 @@
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
+
+module_init(ide_cdrom_init);
+module_exit(ide_cdrom_exit);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)