# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.819 -> 1.820 # include/asm-i386/ide.h 1.9 -> 1.10 # drivers/ide/ide.c 1.33 -> 1.34 # drivers/ide/ide-disk.c 1.27 -> 1.28 # drivers/ide/ide-floppy.c 1.19 -> 1.20 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/10/28 axboe@burns.home.kernel.dk 1.820 # various ide bits # -------------------------------------------- # diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c --- a/drivers/ide/ide-disk.c Mon Oct 28 18:36:04 2002 +++ b/drivers/ide/ide-disk.c Mon Oct 28 18:36:04 2002 @@ -1610,56 +1610,6 @@ #endif } -static int idedisk_suspend(struct device *dev, u32 state, u32 level) -{ - ide_drive_t *drive = dev->driver_data; - - printk("Suspending device %p\n", dev->driver_data); - - /* I hope that every freeze operation from the upper levels have - * already been done... - */ - - if (level != SUSPEND_SAVE_STATE) - return 0; - BUG_ON(in_interrupt()); - - printk("Waiting for commands to finish\n"); - - /* wait until all commands are finished */ - /* FIXME: waiting for spinlocks should be done instead. */ - if (!(HWGROUP(drive))) - printk("No hwgroup?\n"); - while (HWGROUP(drive)->handler) - yield(); - - /* set the drive to standby */ - printk(KERN_INFO "suspending: %s ", drive->name); - if (drive->driver) { - if (drive->driver->standby) - drive->driver->standby(drive); - } - drive->blocked = 1; - - while (HWGROUP(drive)->handler) - yield(); - - return 0; -} - -static int idedisk_resume(struct device *dev, u32 level) -{ - ide_drive_t *drive = dev->driver_data; - - if (level != RESUME_RESTORE_STATE) - return 0; - if (!drive->blocked) - panic("ide: Resume but not suspended?\n"); - - drive->blocked = 0; - return 0; -} - /* This is just a hook for the overall driver tree. */ diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c --- a/drivers/ide/ide-floppy.c Mon Oct 28 18:36:04 2002 +++ b/drivers/ide/ide-floppy.c Mon Oct 28 18:36:04 2002 @@ -1238,6 +1238,21 @@ set_bit(PC_DMA_RECOMMENDED, &pc->flags); } +static int +idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq) +{ + /* + * just support eject for now, it would not be hard to make the + * REQ_BLOCK_PC support fully-featured + */ + if (rq->cmd[0] != IDEFLOPPY_START_STOP_CMD) + return 1; + + idefloppy_init_pc(pc); + memcpy(pc->c, rq->cmd, sizeof(pc->c)); + return 0; +} + /* * idefloppy_do_request is our request handling function. */ @@ -1280,6 +1295,12 @@ idefloppy_create_rw_cmd(floppy, pc, rq, block); } else if (rq->flags & REQ_SPECIAL) { pc = (idefloppy_pc_t *) rq->buffer; + } else if (rq->flags & REQ_BLOCK_PC) { + pc = idefloppy_next_pc_storage(drive); + if (idefloppy_blockpc_cmd(floppy, pc, rq)) { + idefloppy_do_end_request(drive, 0, 0); + return ide_stopped; + } } else { blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue"); diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c --- a/drivers/ide/ide.c Mon Oct 28 18:36:04 2002 +++ b/drivers/ide/ide.c Mon Oct 28 18:36:04 2002 @@ -878,13 +878,12 @@ { ide_startstop_t startstop; unsigned long block; - ide_hwif_t *hwif = HWIF(drive); BUG_ON(!(rq->flags & REQ_STARTED)); #ifdef DEBUG printk("%s: start_request: current=0x%08lx\n", - hwif->name, (unsigned long) rq); + HWIF(drive)->name, (unsigned long) rq); #endif /* bail early if we've exceeded max_failures */ @@ -910,7 +909,7 @@ block = 1; /* redirect MBR access to EZ-Drive partn table */ #if (DISK_RECOVERY_TIME > 0) - while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); + while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME); #endif SELECT_DRIVE(drive); @@ -1128,9 +1127,15 @@ break; } + /* + * we know that the queue isn't empty, but this can happen + * if the q->prep_rq_fn() decides to kill a request + */ rq = elv_next_request(&drive->queue); - if (!rq) + if (!rq) { + hwgroup->busy = !!ata_pending_commands(drive); break; + } if (!rq->bio && ata_pending_commands(drive)) break; @@ -1515,10 +1520,8 @@ { unsigned long flags; ide_hwgroup_t *hwgroup = HWGROUP(drive); - unsigned int major = HWIF(drive)->major; - request_queue_t *q = &drive->queue; - struct list_head *queue_head = &q->queue_head; DECLARE_COMPLETION(wait); + int insert_end = 1, err; #ifdef CONFIG_BLK_DEV_PDC4030 if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL) @@ -1540,29 +1543,35 @@ } rq->rq_disk = drive->disk; - if (action == ide_wait) + + /* + * we need to hold an extra reference to request for safe inspection + * after completion + */ + if (action == ide_wait) { + rq->ref_count++; rq->waiting = &wait; + } + spin_lock_irqsave(&ide_lock, flags); - if (blk_queue_empty(q) || action == ide_preempt) { - if (action == ide_preempt) - hwgroup->rq = NULL; - } else { - if (action == ide_wait || action == ide_end) { - queue_head = queue_head->prev; - } else - queue_head = queue_head->next; + if (action == ide_preempt) { + hwgroup->rq = NULL; + insert_end = 0; } - q->elevator.elevator_add_req_fn(q, rq, queue_head); + __elv_add_request(&drive->queue, rq, insert_end, 0); ide_do_request(hwgroup, 0); spin_unlock_irqrestore(&ide_lock, flags); + + err = 0; if (action == ide_wait) { - /* wait for it to be serviced */ wait_for_completion(&wait); - /* return -EIO if errors */ - return rq->errors ? -EIO : 0; + if (rq->errors) + err = -EIO; + + blk_put_request(rq); } - return 0; + return err; } EXPORT_SYMBOL(ide_do_drive_cmd); @@ -3369,7 +3378,7 @@ list_del_init(&drive->list); ata_attach(drive); } - driver->gen_driver.name = driver->name; + driver->gen_driver.name = (char *) driver->name; driver->gen_driver.bus = &ide_bus_type; driver->gen_driver.remove = ide_drive_remove; return driver_register(&driver->gen_driver); diff -Nru a/include/asm-i386/ide.h b/include/asm-i386/ide.h --- a/include/asm-i386/ide.h Mon Oct 28 18:36:04 2002 +++ b/include/asm-i386/ide.h Mon Oct 28 18:36:04 2002 @@ -70,6 +70,7 @@ int index; for(index = 0; index < MAX_HWIFS; index++) { + memset(&hw, 0, sizeof hw); ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); hw.irq = ide_default_irq(ide_default_io_base(index)); ide_register_hw(&hw, NULL);