(1) ide-taskfile.c: ide_do_drive_cmd(..., ide_preempt) holds channel 
    lock. Do not reacquire. NMI watchdog triggered by just booting 
    computer with IDE cdrom.
(2) ide.c: if we clear BUSY, use goto ... instead of break. There is
    set_bit(IDE_BUSY, ch->active); below loop. Channel stopped by 'hdparm
    -I /dev/hdd': it uses ide_raw_taskfile() which sets REQ_SPECIAL.
    But ide-cd:ide_cdrom_do_request() does not handle REQ_SPECIAL,
    it returns ide_stopped immediately. And ide:do_request() does not
    cope with ide_stopped + empty queue correctly.
(3) unfixed: hdparm -I returns garbage on CDROM: REQ_SPECIAL command
    on CD drive returns success without trying to execute it in
    current driver. I think that ide-cd should handle direct interface
    to its registers properly.
Patch is for 2.5.24+IDE94+IDE95.
					Best regards,
						Petr Vandrovec
						vandrove@vc.cvut.cz
diff -urdN linux/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux/drivers/ide/ide-taskfile.c	Sun Jun 30 00:54:05 2002
+++ linux/drivers/ide/ide-taskfile.c	Sat Jun 29 12:54:48 2002
@@ -209,10 +209,16 @@
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
 	rq->rq_dev = mk_kdev(major,(drive->select.b.unit)<<PARTN_BITS);
-	if (action == ide_wait)
+	if (action == ide_wait) {
 		rq->waiting = &wait;
-
-	spin_lock_irqsave(drive->channel->lock, flags);
+		spin_lock_irqsave(drive->channel->lock, flags);
+	} else if (action == ide_preempt) {
+		if (0 /* SMP... !spin_is_locked(drive->channel->lock) */) {
+			BUG();
+		}
+	} else {
+		BUG();
+	}
 
 	if (blk_queue_empty(&drive->queue) || action == ide_preempt) {
 		if (action == ide_preempt)
@@ -227,9 +233,9 @@
 
 	do_ide_request(q);
 
-	spin_unlock_irqrestore(drive->channel->lock, flags);
-
 	if (action == ide_wait) {
+		spin_unlock_irqrestore(drive->channel->lock, flags);
+
 		wait_for_completion(&wait);	/* wait for it to be serviced */
 		return rq->errors ? -EIO : 0;	/* return -EIO if errors */
 	}
diff -urdN linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux/drivers/ide/ide.c	Sun Jun 30 00:54:05 2002
+++ linux/drivers/ide/ide.c	Sat Jun 29 23:45:47 2002
@@ -864,7 +864,7 @@
 			if (!ata_can_queue(drive)) {
 				if (!ata_pending_commands(drive))
 					clear_bit(IDE_BUSY, ch->active);
-				break;
+				goto dontsetbusy;
 			}
 
 			drive->sleep = 0;
@@ -889,7 +889,7 @@
 				if (!ata_pending_commands(drive))
 					clear_bit(IDE_BUSY, ch->active);
 				drive->rq = NULL;
-				break;
+				goto dontsetbusy;
 			}
 
 			/* If there are queued commands, we can't start a
@@ -906,6 +906,7 @@
 		/* make sure the BUSY bit is set */
 		/* FIXME: perhaps there is some place where we miss to set it? */
 		set_bit(IDE_BUSY, ch->active);
+dontsetbusy:;		
 	}
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/