diff -uNr -X exclude linux-2.6.0-test11/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c --- linux-2.6.0-test11/arch/i386/kernel/mpparse.c 2003-12-08 00:29:12.000000000 +0100 +++ linux/arch/i386/kernel/mpparse.c 2003-12-08 00:33:52.671960352 +0100 @@ -962,7 +962,8 @@ */ for (i = 0; i < mp_irq_entries; i++) { if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) - && (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) { + && (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq) + && (mp_irqs[i].mpc_irqtype == intsrc.mpc_irqtype)) { mp_irqs[i] = intsrc; found = 1; break; diff -uNr -X exclude linux-2.6.0-test11/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c --- linux-2.6.0-test11/arch/i386/mm/fault.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/arch/i386/mm/fault.c 2003-12-08 00:33:50.645268456 +0100 @@ -359,7 +359,8 @@ return; tsk->thread.cr2 = address; - tsk->thread.error_code = error_code; + /* Kernel addresses are always protection faults */ + tsk->thread.error_code = error_code | (address >= TASK_SIZE); tsk->thread.trap_no = 14; info.si_signo = SIGSEGV; info.si_errno = 0; diff -uNr -X exclude linux-2.6.0-test11/arch/i386/pci/fixup.c linux/arch/i386/pci/fixup.c --- linux-2.6.0-test11/arch/i386/pci/fixup.c 2003-12-08 00:29:12.000000000 +0100 +++ linux/arch/i386/pci/fixup.c 2003-12-08 00:33:52.521983152 +0100 @@ -187,6 +187,22 @@ dev->transparent = 1; } +/* + * Halt Disconnect and Stop Grant Disconnect (bit 4 at offset 0x6F) + * must be disabled when APIC is used (or lockups will happen). + */ +static void __devinit pci_fixup_nforce2_disconnect(struct pci_dev *d) +{ + u8 t; + + pci_read_config_byte(d, 0x6F, &t); + if (t & 0x10) { + printk(KERN_INFO "PCI: disabling nForce2 Halt Disconnect" + " and Stop Grant Disconnect\n"); + pci_write_config_byte(d, 0x6F, (t & 0xef)); + } +} + struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx }, @@ -205,5 +221,6 @@ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810 }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2_disconnect }, { 0 } }; diff -uNr -X exclude linux-2.6.0-test11/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-2.6.0-test11/drivers/block/ll_rw_blk.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/block/ll_rw_blk.c 2003-12-08 00:33:51.201183944 +0100 @@ -780,11 +780,6 @@ "REQ_PM_SUSPEND", "REQ_PM_RESUME", "REQ_PM_SHUTDOWN", - "REQ_IDETAPE_PC1", - "REQ_IDETAPE_PC2", - "REQ_IDETAPE_READ", - "REQ_IDETAPE_WRITE", - "REQ_IDETAPE_READ_BUFFER", }; void blk_dump_rq_flags(struct request *rq, char *msg) diff -uNr -X exclude linux-2.6.0-test11/drivers/i2c/busses/i2c-nforce2.c linux/drivers/i2c/busses/i2c-nforce2.c --- linux-2.6.0-test11/drivers/i2c/busses/i2c-nforce2.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/i2c/busses/i2c-nforce2.c 2003-12-08 00:33:50.646268304 +0100 @@ -147,7 +147,7 @@ case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) - outb_p(data->byte, NVIDIA_SMB_DATA); + outb_p(command, NVIDIA_SMB_CMD); protocol |= NVIDIA_SMB_PRTCL_BYTE; break; diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/ide-io.c linux/drivers/ide/ide-io.c --- linux-2.6.0-test11/drivers/ide/ide-io.c 2003-12-08 00:29:12.000000000 +0100 +++ linux/drivers/ide/ide-io.c 2003-12-08 00:33:52.834935576 +0100 @@ -54,37 +54,6 @@ #include #include -#if (DISK_RECOVERY_TIME > 0) - -#error So the User Has To Fix the Compilation And Stop Hacking Port 0x43. Does anyone ever use this anyway ?? - -/* - * For really screwy hardware (hey, at least it *can* be used with Linux) - * we can enforce a minimum delay time between successive operations. - */ -static unsigned long read_timer (ide_hwif_t *hwif) -{ - unsigned long t, flags; - int i; - - /* FIXME this is completely unsafe! */ - local_irq_save(flags); - t = jiffies * 11932; - outb_p(0, 0x43); - i = inb_p(0x40); - i |= inb_p(0x40) << 8; - local_irq_restore(flags); - return (t - i); -} -#endif /* DISK_RECOVERY_TIME */ - -static inline void set_recovery_timer (ide_hwif_t *hwif) -{ -#if (DISK_RECOVERY_TIME > 0) - hwif->last_time = read_timer(hwif); -#endif /* DISK_RECOVERY_TIME */ -} - /** * ide_end_request - complete an IDE I/O * @drive: IDE device for the I/O @@ -653,10 +622,6 @@ if (block == 0 && drive->remap_0_to_1 == 1) block = 1; /* redirect MBR access to EZ-Drive partn table */ -#if (DISK_RECOVERY_TIME > 0) - while ((read_timer() - HWIF(drive)->last_time) < DISK_RECOVERY_TIME); -#endif - if (blk_pm_suspend_request(rq) && rq->pm->pm_step == ide_pm_state_start_suspend) /* Mark drive blocked when starting the suspend sequence. */ @@ -1116,7 +1081,6 @@ startstop = DRIVER(drive)->error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); } - set_recovery_timer(hwif); drive->service_time = jiffies - drive->service_start; spin_lock_irq(&ide_lock); enable_irq(hwif->irq); @@ -1313,7 +1277,6 @@ * same irq as is currently being serviced here, and Linux * won't allow another of the same (on any CPU) until we return. */ - set_recovery_timer(HWIF(drive)); drive->service_time = jiffies - drive->service_start; if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c --- linux-2.6.0-test11/drivers/ide/ide-tape.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/ide/ide-tape.c 2003-12-08 00:33:51.207183032 +0100 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-tape.c Version 1.17b Oct, 2002 + * linux/drivers/ide/ide-tape.c Version 1.19 Nov, 2003 * * Copyright (C) 1995 - 1999 Gadi Oxman * @@ -422,7 +422,7 @@ * sharing a (fast) ATA-2 disk with any (slow) new ATAPI device. */ -#define IDETAPE_VERSION "1.17b-ac1" +#define IDETAPE_VERSION "1.19" #include #include @@ -450,9 +450,6 @@ #include #include - -#define NO_LONGER_REQUIRED (1) - /* * OnStream support */ @@ -652,9 +649,11 @@ #define IDETAPE_PC_STACK (10 + IDETAPE_MAX_PC_RETRIES) /* - * Some tape drives require a long irq timeout + * Some drives (for example, Seagate STT3401A Travan) require a very long + * timeout, because they don't return an interrupt or clear their busy bit + * until after the command completes (even retension commands). */ -#define IDETAPE_WAIT_CMD (60*HZ) +#define IDETAPE_WAIT_CMD (900*HZ) /* * The following parameter is used to select the point in the internal @@ -1032,6 +1031,10 @@ /* the door is currently locked */ int door_locked; + /* the tape hardware is write protected */ + char drv_write_prot; + /* the tape is write protected (hardware or opened as read-only) */ + char write_prot; /* * OnStream flags @@ -1164,6 +1167,8 @@ #define IDETAPE_DRQ_INTERRUPT 6 /* DRQ interrupt device */ #define IDETAPE_READ_ERROR 7 #define IDETAPE_PIPELINE_ACTIVE 8 /* pipeline active */ +/* 0 = no tape is loaded, so we don't rewind after ejecting */ +#define IDETAPE_MEDIUM_PRESENT 9 /* * Supported ATAPI tape drives packet commands @@ -1211,10 +1216,14 @@ * requests to the tail of our block device request queue and wait * for their completion. */ -#define idetape_request(rq) \ - ((rq)->flags & (REQ_IDETAPE_PC1 | REQ_IDETAPE_PC2 | \ - REQ_IDETAPE_READ | REQ_IDETAPE_WRITE | \ - REQ_IDETAPE_READ_BUFFER)) + +enum { + REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */ + REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */ + REQ_IDETAPE_READ = (1 << 2), + REQ_IDETAPE_WRITE = (1 << 3), + REQ_IDETAPE_READ_BUFFER = (1 << 4), +}; /* * Error codes which are returned in rq->errors to the higher part @@ -1665,6 +1674,20 @@ idetape_update_buffers(pc); } + /* + * If error was the result of a zero-length read or write command, + * with sense key=5, asc=0x22, ascq=0, let it slide. Some drives + * (i.e. Seagate STT3401A Travan) don't support 0-length read/writes. + */ + if ((pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) + && pc->c[4] == 0 && pc->c[3] == 0 && pc->c[2] == 0) { /* length==0 */ + if (result->sense_key == 5) { + /* don't report an error, everything's ok */ + pc->error = 0; + /* don't retry read/write */ + set_bit(PC_ABORT, &pc->flags); + } + } if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) { pc->error = IDETAPE_ERROR_FILEMARK; set_bit(PC_ABORT, &pc->flags); @@ -1805,10 +1828,15 @@ } } -static void idetape_abort_pipeline (ide_drive_t *drive, idetape_stage_t *last_stage) +/* + * This will free all the pipeline stages starting from new_last_stage->next + * to the end of the list, and point tape->last_stage to new_last_stage. + */ +static void idetape_abort_pipeline(ide_drive_t *drive, + idetape_stage_t *new_last_stage) { idetape_tape_t *tape = drive->driver_data; - idetape_stage_t *stage = tape->next_stage; + idetape_stage_t *stage = new_last_stage->next; idetape_stage_t *nstage; #if IDETAPE_DEBUG_LOG @@ -1822,9 +1850,9 @@ --tape->nr_pending_stages; stage = nstage; } - tape->last_stage = last_stage; - if (last_stage) - last_stage->next = NULL; + if (new_last_stage) + new_last_stage->next = NULL; + tape->last_stage = new_last_stage; tape->next_stage = NULL; } @@ -1868,7 +1896,7 @@ tape->active_stage = NULL; tape->active_data_request = NULL; tape->nr_pending_stages--; - if (rq->flags & REQ_IDETAPE_WRITE) { + if (rq->cmd[0] & REQ_IDETAPE_WRITE) { #if ONSTREAM_DEBUG if (tape->debug_level >= 2) { if (tape->onstream) { @@ -1914,7 +1942,7 @@ } } } - } else if (rq->flags & REQ_IDETAPE_READ) { + } else if (rq->cmd[0] & REQ_IDETAPE_READ) { if (error == IDETAPE_ERROR_EOD) { set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); idetape_abort_pipeline(drive, active_stage); @@ -1972,6 +2000,13 @@ pc->callback = &idetape_request_sense_callback; } +static void idetape_init_rq(struct request *rq, u8 cmd) +{ + memset(rq, 0, sizeof(*rq)); + rq->flags = REQ_SPECIAL; + rq->cmd[0] = cmd; +} + /* * idetape_queue_pc_head generates a new packet command request in front * of the request queue, before the current request, so that it will be @@ -1993,8 +2028,7 @@ */ static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq) { - memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_IDETAPE_PC1; + idetape_init_rq(rq, REQ_IDETAPE_PC1); rq->buffer = (char *) pc; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -2430,7 +2464,14 @@ if (page_code != IDETAPE_BLOCK_DESCRIPTOR) pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */ pc->c[2] = page_code; - pc->c[3] = 255; /* Don't limit the returned information */ + /* + * Changed pc->c[3] to 0 (255 will at best return unused info). + * + * For SCSI this byte is defined as subpage instead of high byte + * of length and some IDE drives seem to interpret it this way + * and return an error when 255 is used. + */ + pc->c[3] = 0; pc->c[4] = 255; /* (We will just discard data in that case) */ if (page_code == IDETAPE_BLOCK_DESCRIPTOR) pc->request_transfer = 12; @@ -2544,8 +2585,9 @@ if (status.b.dsc) { if (status.b.check) { /* Error detected */ - printk(KERN_ERR "ide-tape: %s: I/O error, ",tape->name); - + if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD) + printk(KERN_ERR "ide-tape: %s: I/O error, ", + tape->name); /* Retry operation */ return idetape_retry_pc(drive); } @@ -2697,7 +2739,7 @@ if (tape->debug_level >= 5) printk(KERN_INFO "ide-tape: rq_status: %d, " "dev: %s, cmd: %ld, errors: %d\n", rq->rq_status, - rq->rq_disk->disk_name, rq->flags, rq->errors); + rq->rq_disk->disk_name, rq->cmd[0], rq->errors); #endif if (tape->debug_level >= 2) printk(KERN_INFO "ide-tape: sector: %ld, " @@ -2705,11 +2747,11 @@ rq->sector, rq->nr_sectors, rq->current_nr_sectors); #endif /* IDETAPE_DEBUG_LOG */ - if (!idetape_request(rq)) { + if ((rq->flags & REQ_SPECIAL) == 0) { /* * We do not support buffer cache originated requests. */ - printk(KERN_NOTICE "ide-tape: %s: Unsupported command in " + printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%ld)\n", drive->name, rq->flags); ide_end_request(drive, 0, 0); return ide_stopped; @@ -2746,7 +2788,7 @@ */ if (tape->onstream) status.b.dsc = 1; - if (!drive->dsc_overlap && !(rq->flags & REQ_IDETAPE_PC2)) + if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2)) set_bit(IDETAPE_IGNORE_DSC, &tape->flags); /* @@ -2760,7 +2802,7 @@ if (tape->tape_still_time > 100 && tape->tape_still_time < 200) tape->measure_insert_time = 1; if (tape->req_buffer_fill && - (rq->flags & (REQ_IDETAPE_WRITE | REQ_IDETAPE_READ))) { + (rq->cmd[0] & (REQ_IDETAPE_WRITE | REQ_IDETAPE_READ))) { tape->req_buffer_fill = 0; tape->writes_since_buffer_fill = 0; tape->reads_since_buffer_fill = 0; @@ -2774,12 +2816,12 @@ tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); calculate_speeds(drive); if (tape->onstream && tape->max_frames && - (((rq->flags & REQ_IDETAPE_WRITE) && + (((rq->cmd[0] & REQ_IDETAPE_WRITE) && ( tape->cur_frames == tape->max_frames || ( tape->speed_control && tape->cur_frames > 5 && (tape->insert_speed > tape->max_insert_speed || (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 */) ) ) ) ) || - ((rq->flags & REQ_IDETAPE_READ) && + ((rq->cmd[0] & REQ_IDETAPE_READ) && ( tape->cur_frames == 0 || ( tape->speed_control && (tape->cur_frames < tape->max_frames - 5) && tape->insert_speed > tape->max_insert_speed ) ) && rq->nr_sectors) ) ) { @@ -2787,7 +2829,7 @@ if (tape->debug_level >= 4) printk(KERN_INFO "ide-tape: postponing request, " "cmd %ld, cur %d, max %d\n", - rq->flags, tape->cur_frames, tape->max_frames); + rq->cmd[0], tape->cur_frames, tape->max_frames); #endif if (tape->postpone_cnt++ < 500) { status.b.dsc = 0; @@ -2808,7 +2850,7 @@ } else if ((signed long) (jiffies - tape->dsc_timeout) > 0) { printk(KERN_ERR "ide-tape: %s: DSC timeout\n", tape->name); - if (rq->flags & REQ_IDETAPE_PC2) { + if (rq->cmd[0] & REQ_IDETAPE_PC2) { idetape_media_access_finished(drive); return ide_stopped; } else { @@ -2819,7 +2861,7 @@ idetape_postpone_request(drive); return ide_stopped; } - if (rq->flags & REQ_IDETAPE_READ) { + if (rq->cmd[0] & REQ_IDETAPE_READ) { tape->buffer_head++; #if USE_IOTRACE IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); @@ -2836,7 +2878,7 @@ idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); goto out; } - if (rq->flags & REQ_IDETAPE_WRITE) { + if (rq->cmd[0] & REQ_IDETAPE_WRITE) { tape->buffer_head++; #if USE_IOTRACE IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); @@ -2854,19 +2896,19 @@ idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); goto out; } - if (rq->flags & REQ_IDETAPE_READ_BUFFER) { + if (rq->cmd[0] & REQ_IDETAPE_READ_BUFFER) { tape->postpone_cnt = 0; pc = idetape_next_pc_storage(drive); idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); goto out; } - if (rq->flags & REQ_IDETAPE_PC1) { + if (rq->cmd[0] & REQ_IDETAPE_PC1) { pc = (idetape_pc_t *) rq->buffer; - rq->flags &= ~(REQ_IDETAPE_PC1); - rq->flags |= REQ_IDETAPE_PC2; + rq->cmd[0] &= ~(REQ_IDETAPE_PC1); + rq->cmd[0] |= REQ_IDETAPE_PC2; goto out; } - if (rq->flags & REQ_IDETAPE_PC2) { + if (rq->cmd[0] & REQ_IDETAPE_PC2) { idetape_media_access_finished(drive); return ide_stopped; } @@ -3163,7 +3205,7 @@ idetape_tape_t *tape = drive->driver_data; #if IDETAPE_DEBUG_BUGS - if (rq == NULL || !idetape_request(rq)) { + if (rq == NULL || (rq->flags & REQ_SPECIAL) == 0) { printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n"); return; } @@ -3269,8 +3311,7 @@ { struct request rq; - memset(&rq, 0, sizeof(rq)); - rq.flags = REQ_IDETAPE_PC1; + idetape_init_rq(&rq, REQ_IDETAPE_PC1); rq.buffer = (char *) pc; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -3295,25 +3336,28 @@ { idetape_tape_t *tape = drive->driver_data; idetape_pc_t pc; + int load_attempted = 0; /* * Wait for the tape to become ready */ + set_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); timeout += jiffies; while (time_before(jiffies, timeout)) { idetape_create_test_unit_ready_cmd(&pc); if (!__idetape_queue_pc_tail(drive, &pc)) return 0; - if (tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) { + if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) + || (tape->asc == 0x3A)) { /* no media */ + if (load_attempted) + return -ENOMEDIUM; idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK); __idetape_queue_pc_tail(drive, &pc); - idetape_create_test_unit_ready_cmd(&pc); - if (!__idetape_queue_pc_tail(drive, &pc)) - return 0; - } - if (!(tape->sense_key == 2 && tape->asc == 4 && - (tape->ascq == 1 || tape->ascq == 8))) - break; + load_attempted = 1; + /* not about to be ready */ + } else if (!(tape->sense_key == 2 && tape->asc == 4 && + (tape->ascq == 1 || tape->ascq == 8))) + return -EIO; current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ / 10); } @@ -3369,25 +3413,10 @@ printk(KERN_INFO "ide-tape: Reached idetape_read_position\n"); #endif /* IDETAPE_DEBUG_LOG */ -#ifdef NO_LONGER_REQUIRED - idetape_flush_tape_buffers(drive); -#endif idetape_create_read_position_cmd(&pc); if (idetape_queue_pc_tail(drive, &pc)) return -1; position = tape->first_frame_position; -#ifdef NO_LONGER_REQUIRED - if (tape->onstream) { - if ((position != tape->last_frame_position - tape->blocks_in_buffer) && - (position != tape->last_frame_position + tape->blocks_in_buffer)) { - if (tape->blocks_in_buffer == 0) { - printk("ide-tape: %s: correcting read position %d, %d, %d\n", tape->name, position, tape->last_frame_position, tape->blocks_in_buffer); - position = tape->last_frame_position; - tape->first_frame_position = position; - } - } - } -#endif return position; } @@ -3436,6 +3465,8 @@ if (tape->chrdev_direction != idetape_direction_read) return 0; + + /* Remove merge stage. */ cnt = tape->merge_stage_size / tape->tape_block_size; if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags)) ++cnt; /* Filemarks count as 1 sector */ @@ -3444,9 +3475,12 @@ __idetape_kfree_stage(tape->merge_stage); tape->merge_stage = NULL; } + + /* Clear pipeline flags. */ clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); tape->chrdev_direction = idetape_direction_none; - + + /* Remove pipeline stages. */ if (tape->first_stage == NULL) return 0; @@ -3546,8 +3580,7 @@ } #endif /* IDETAPE_DEBUG_BUGS */ - memset(&rq, 0, sizeof(rq)); - rq.flags = cmd; + idetape_init_rq(&rq, cmd); rq.special = (void *)bh; rq.sector = tape->first_frame_position; rq.nr_sectors = rq.current_nr_sectors = blocks; @@ -3596,8 +3629,7 @@ printk(KERN_INFO "ide-tape: %s: read back logical block %d, data %x %x %x %x\n", tape->name, logical_blk_num, *p++, *p++, *p++, *p++); #endif rq = &stage->rq; - memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_IDETAPE_WRITE; + idetape_init_rq(rq, REQ_IDETAPE_WRITE); rq->sector = tape->first_frame_position; rq->nr_sectors = rq->current_nr_sectors = tape->capabilities.ctl; idetape_init_stage(drive, stage, OS_FRAME_TYPE_DATA, logical_blk_num++); @@ -3871,8 +3903,7 @@ } } rq = &new_stage->rq; - memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_IDETAPE_WRITE; + idetape_init_rq(rq, REQ_IDETAPE_WRITE); /* Doesn't actually matter - We always assume sequential access */ rq->sector = tape->first_frame_position; rq->nr_sectors = rq->current_nr_sectors = blocks; @@ -4059,19 +4090,22 @@ * Issue a read 0 command to ensure that DSC handshake * is switched from completion mode to buffer available * mode. + * No point in issuing this if DSC overlap isn't supported, + * some drives (Seagate STT3401A) will return an error. */ - bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh); - if (bytes_read < 0) { - __idetape_kfree_stage(tape->merge_stage); - tape->merge_stage = NULL; - tape->chrdev_direction = idetape_direction_none; - return bytes_read; + if (drive->dsc_overlap) { + bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh); + if (bytes_read < 0) { + __idetape_kfree_stage(tape->merge_stage); + tape->merge_stage = NULL; + tape->chrdev_direction = idetape_direction_none; + return bytes_read; + } } } if (tape->restart_speed_control_req) idetape_restart_speed_control(drive); - memset(&rq, 0, sizeof(rq)); - rq.flags = REQ_IDETAPE_READ; + idetape_init_rq(&rq, REQ_IDETAPE_READ); rq.sector = tape->first_frame_position; rq.nr_sectors = rq.current_nr_sectors = blocks; if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) && @@ -4898,6 +4932,10 @@ return -ENXIO; } + /* The drive is write protected. */ + if (tape->write_prot) + return -EACCES; + #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 3) printk(KERN_INFO "ide-tape: Reached idetape_chrdev_write, " @@ -4979,13 +5017,17 @@ * Issue a write 0 command to ensure that DSC handshake * is switched from completion mode to buffer available * mode. + * No point in issuing this if DSC overlap isn't supported, + * some drives (Seagate STT3401A) will return an error. */ - retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh); - if (retval < 0) { - __idetape_kfree_stage(tape->merge_stage); - tape->merge_stage = NULL; - tape->chrdev_direction = idetape_direction_none; - return retval; + if (drive->dsc_overlap) { + retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh); + if (retval < 0) { + __idetape_kfree_stage(tape->merge_stage); + tape->merge_stage = NULL; + tape->chrdev_direction = idetape_direction_none; + return retval; + } } #if ONSTREAM_DEBUG if (tape->debug_level >= 2) @@ -5141,7 +5183,7 @@ * Note: * * MTBSF and MTBSFM are not supported when the tape doesn't - * supports spacing over filemarks in the reverse direction. + * support spacing over filemarks in the reverse direction. * In this case, MTFSFM is also usually not supported (it is * supported in the rare case in which we crossed the filemark * during our read-ahead pipelined operation mode). @@ -5211,6 +5253,8 @@ } switch (mt_op) { case MTWEOF: + if (tape->write_prot) + return -EACCES; idetape_discard_read_pipeline(drive, 1); for (i = 0; i < mt_count; i++) { retval = idetape_write_filemark(drive); @@ -5231,9 +5275,21 @@ return (idetape_queue_pc_tail(drive, &pc)); case MTUNLOAD: case MTOFFL: + /* + * If door is locked, attempt to unlock before + * attempting to eject. + */ + if (tape->door_locked) { + if (idetape_create_prevent_cmd(drive, &pc, 0)) + if (!idetape_queue_pc_tail(drive, &pc)) + tape->door_locked = DOOR_UNLOCKED; + } idetape_discard_read_pipeline(drive, 0); idetape_create_load_unload_cmd(drive, &pc,!IDETAPE_LU_LOAD_MASK); - return (idetape_queue_pc_tail(drive, &pc)); + retval = idetape_queue_pc_tail(drive, &pc); + if (!retval) + clear_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); + return retval; case MTNOP: idetape_discard_read_pipeline(drive, 0); return (idetape_flush_tape_buffers(drive)); @@ -5409,6 +5465,8 @@ mtget.mt_gstat |= GMT_EOD(0xffffffff); if (position <= OS_DATA_STARTFRAME1) mtget.mt_gstat |= GMT_BOT(0xffffffff); + } else if (tape->drv_write_prot) { + mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); } if (copy_to_user((char *) arg,(char *) &mtget, sizeof(struct mtget))) return -EFAULT; @@ -5530,6 +5588,8 @@ return 1; } +static void idetape_get_blocksize_from_block_descriptor(ide_drive_t *drive); + /* * Our character device open function. */ @@ -5539,7 +5599,8 @@ ide_drive_t *drive; idetape_tape_t *tape; idetape_pc_t pc; - + int retval; + #if IDETAPE_DEBUG_LOG printk(KERN_INFO "ide-tape: Reached idetape_chrdev_open\n"); #endif /* IDETAPE_DEBUG_LOG */ @@ -5552,11 +5613,7 @@ if (test_and_set_bit(IDETAPE_BUSY, &tape->flags)) return -EBUSY; - if (!tape->onstream) { - idetape_read_position(drive); - if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags)) - (void) idetape_rewind_tape(drive); - } else { + if (tape->onstream) { if (minor & 64) { tape->tape_block_size = tape->stage_size = 32768 + 512; tape->raw = 1; @@ -5566,16 +5623,42 @@ } idetape_onstream_mode_sense_tape_parameter_page(drive, tape->debug_level); } - if (idetape_wait_ready(drive, 60 * HZ)) { + retval = idetape_wait_ready(drive, 60 * HZ); + if (retval) { clear_bit(IDETAPE_BUSY, &tape->flags); printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); - return -EBUSY; + return retval; } - if (tape->onstream) - idetape_read_position(drive); + + idetape_read_position(drive); + if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags)) + (void)idetape_rewind_tape(drive); + if (tape->chrdev_direction != idetape_direction_read) clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); + /* Read block size and write protect status from drive. */ + idetape_get_blocksize_from_block_descriptor(drive); + + /* Set write protect flag if device is opened as read-only. */ + if ((filp->f_flags & O_ACCMODE) == O_RDONLY) + tape->write_prot = 1; + else + tape->write_prot = tape->drv_write_prot; + + /* Make sure drive isn't write protected if user wants to write. */ + if (tape->write_prot) { + if ((filp->f_flags & O_ACCMODE) == O_WRONLY || + (filp->f_flags & O_ACCMODE) == O_RDWR) { + clear_bit(IDETAPE_BUSY, &tape->flags); + return -EROFS; + } + } + + /* + * Lock the tape drive door so user can't eject. + * Analyze headers for OnStream drives. + */ if (tape->chrdev_direction == idetape_direction_none) { if (idetape_create_prevent_cmd(drive, &pc, 1)) { if (!idetape_queue_pc_tail(drive, &pc)) { @@ -5638,7 +5721,7 @@ __idetape_kfree_stage(tape->cache_stage); tape->cache_stage = NULL; } - if (minor < 128) + if (minor < 128 && test_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags)) (void) idetape_rewind_tape(drive); if (tape->chrdev_direction == idetape_direction_none) { if (tape->door_locked == DOOR_LOCKED) { @@ -6059,6 +6142,8 @@ header = (idetape_mode_parameter_header_t *) pc.buffer; block_descrp = (idetape_parameter_block_descriptor_t *) (pc.buffer + sizeof(idetape_mode_parameter_header_t)); tape->tape_block_size =( block_descrp->length[0]<<16) + (block_descrp->length[1]<<8) + block_descrp->length[2]; + tape->drv_write_prot = (header->dsp & 0x80) >> 7; + #if IDETAPE_DEBUG_INFO printk(KERN_INFO "ide-tape: Adjusted block size - %d\n", tape->tape_block_size); #endif /* IDETAPE_DEBUG_INFO */ @@ -6139,6 +6224,9 @@ } } #endif /* CONFIG_BLK_DEV_IDEPCI */ + /* Seagate Travan drives do not support DSC overlap. */ + if (strstr(drive->id->model, "Seagate STT3401")) + drive->dsc_overlap = 0; tape->drive = drive; tape->minor = minor; tape->name[0] = 'h'; diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/cmd640.c linux/drivers/ide/pci/cmd640.c --- linux-2.6.0-test11/drivers/ide/pci/cmd640.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/ide/pci/cmd640.c 2003-12-08 00:33:51.864083168 +0100 @@ -213,13 +213,13 @@ static void put_cmd640_reg_pci1 (u16 reg, u8 val) { - outb_p((reg & 0xfc) | cmd640_key, 0xcf8); + outl_p((reg & 0xfc) | cmd640_key, 0xcf8); outb_p(val, (reg & 3) | 0xcfc); } static u8 get_cmd640_reg_pci1 (u16 reg) { - outb_p((reg & 0xfc) | cmd640_key, 0xcf8); + outl_p((reg & 0xfc) | cmd640_key, 0xcf8); return inb_p((reg & 3) | 0xcfc); } diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/pdc202xx_new.c linux/drivers/ide/pci/pdc202xx_new.c --- linux-2.6.0-test11/drivers/ide/pci/pdc202xx_new.c 2003-12-08 00:29:12.000000000 +0100 +++ linux/drivers/ide/pci/pdc202xx_new.c 2003-12-08 00:33:52.996910952 +0100 @@ -36,60 +36,20 @@ #define PDC202_DEBUG_CABLE 0 -#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -static u8 pdcnew_proc = 0; -#define PDC202_MAX_DEVS 5 -static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS]; -static int n_pdc202_devs; - -static char * pdcnew_info(char *buf, struct pci_dev *dev) -{ - char *p = buf; - - p += sprintf(p, "\n "); - switch(dev->device) { - case PCI_DEVICE_ID_PROMISE_20277: - p += sprintf(p, "SBFastTrak 133 Lite"); break; - case PCI_DEVICE_ID_PROMISE_20276: - p += sprintf(p, "MBFastTrak 133 Lite"); break; - case PCI_DEVICE_ID_PROMISE_20275: - p += sprintf(p, "MBUltra133"); break; - case PCI_DEVICE_ID_PROMISE_20271: - p += sprintf(p, "FastTrak TX2000"); break; - case PCI_DEVICE_ID_PROMISE_20270: - p += sprintf(p, "FastTrak LP/TX2/TX4"); break; - case PCI_DEVICE_ID_PROMISE_20269: - p += sprintf(p, "Ultra133 TX2"); break; - case PCI_DEVICE_ID_PROMISE_20268: - p += sprintf(p, "Ultra100 TX2"); break; - default: - p += sprintf(p, "Ultra series"); break; - break; - } - p += sprintf(p, " Chipset.\n"); - return (char *)p; -} - -static int pdcnew_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - int i, len; - - for (i = 0; i < n_pdc202_devs; i++) { - struct pci_dev *dev = pdc202_devs[i]; - p = pdcnew_info(buffer, dev); - } - /* p - buffer must be less than 4k! */ - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} -#endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ +struct pdcnew_name { + u16 dev_id; + const char *name; +}; +static struct pdcnew_name __initdata pdcnew_names[] = { + { PCI_DEVICE_ID_PROMISE_20277, "SBFastTrak 133 Lite" }, + { PCI_DEVICE_ID_PROMISE_20276, "MBFastTrak 133 Lite" }, + { PCI_DEVICE_ID_PROMISE_20275, "MBUltra133", }, + { PCI_DEVICE_ID_PROMISE_20271, "FastTrak TX2000", }, + { PCI_DEVICE_ID_PROMISE_20270, "FastTrak LP/TX2/TX4", }, + { PCI_DEVICE_ID_PROMISE_20269, "Ultra133 TX2" }, + { PCI_DEVICE_ID_PROMISE_20268, "Ultra100 TX2" }, +}; static u8 pdcnew_ratemask (ide_drive_t *drive) { @@ -515,6 +475,15 @@ static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char *name) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pdcnew_names); i++) + if (pdcnew_names[i].dev_id == dev->device) { + printk(KERN_INFO "%s: %s on pci%s\n", name, + pdcnew_names[i].name, pci_name(dev)); + break; + } + if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); @@ -522,15 +491,6 @@ name, dev->resource[PCI_ROM_RESOURCE].start); } -#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) - pdc202_devs[n_pdc202_devs++] = dev; - - if (!pdcnew_proc) { - pdcnew_proc = 1; - ide_pci_register_host_proc(&pdcnew_procs[0]); - } -#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */ - return dev->irq; } diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/pdc202xx_new.h linux/drivers/ide/pci/pdc202xx_new.h --- linux-2.6.0-test11/drivers/ide/pci/pdc202xx_new.h 2003-12-08 00:29:12.000000000 +0100 +++ linux/drivers/ide/pci/pdc202xx_new.h 2003-12-08 00:33:52.997910800 +0100 @@ -5,8 +5,6 @@ #include #include -#define DISPLAY_PDC202XX_TIMINGS - #ifndef SPLIT_BYTE #define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) #endif @@ -162,27 +160,6 @@ set_2regs(0x13,(c)); \ } while(0) -#define DISPLAY_PDC202XX_TIMINGS - -#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -static u8 pdcnew_proc; - -static int pdcnew_get_info(char *, char **, off_t, int); - -static ide_pci_host_proc_t pdcnew_procs[] __initdata = { - { - .name = "pdcnew", - .set = 1, - .get_info = pdcnew_get_info, - .parent = NULL, - }, -}; -#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */ - - static void init_setup_pdcnew(struct pci_dev *, ide_pci_device_t *); static void init_setup_pdc20270(struct pci_dev *, ide_pci_device_t *); static void init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d); diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/pdc202xx_old.c linux/drivers/ide/pci/pdc202xx_old.c --- linux-2.6.0-test11/drivers/ide/pci/pdc202xx_old.c 2003-12-08 00:29:12.000000000 +0100 +++ linux/drivers/ide/pci/pdc202xx_old.c 2003-12-08 00:33:52.369006408 +0100 @@ -361,16 +361,38 @@ return ((u8)(CIS & mask)); } +/* + * Set the control register to use the 66MHz system + * clock for UDMA 3/4/5 mode operation when necessary. + * + * It may also be possible to leave the 66MHz clock on + * and readjust the timing parameters. + */ +static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) +{ + unsigned long clock_reg = hwif->dma_master + 0x11; + u8 clock = hwif->INB(clock_reg); + + hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); +} + +static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) +{ + unsigned long clock_reg = hwif->dma_master + 0x11; + u8 clock = hwif->INB(clock_reg); + + hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); +} + static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; u32 drive_conf = 0; - u8 mask = hwif->channel ? 0x08 : 0x02; u8 drive_pci = 0x60 + (drive->dn << 2); u8 test1 = 0, test2 = 0, speed = -1; - u8 AP = 0, CLKSPD = 0, cable = 0; + u8 AP = 0, cable = 0; u8 ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0; @@ -394,21 +416,6 @@ BUG(); } - CLKSPD = hwif->INB(hwif->dma_master + 0x11); - - /* - * Set the control register to use the 66Mhz system - * clock for UDMA 3/4 mode operation. If one drive on - * a channel is U66 capable but the other isn't we - * fall back to U33 mode. The BIOS INT 13 hooks turn - * the clock on then off for each read/write issued. I don't - * do that here because it would require modifying the - * kernel, separating the fop routines from the kernel or - * somehow hooking the fops calls. It may also be possible to - * leave the 66Mhz clock on and readjust the timing - * parameters. - */ - if ((ultra_66) && (cable)) { #ifdef DEBUG printk(KERN_DEBUG "ULTRA 66/100/133: %s channel of Ultra 66/100/133 " @@ -416,29 +423,12 @@ hwif->channel ? "Secondary" : "Primary"); printk(KERN_DEBUG " Switching to Ultra33 mode.\n"); #endif /* DEBUG */ - /* Primary : zero out second bit */ - /* Secondary : zero out fourth bit */ - hwif->OUTB(CLKSPD & ~mask, (hwif->dma_master + 0x11)); printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); - } else { - if (ultra_66) { - /* - * check to make sure drive on same channel - * is u66 capable - */ - if (hwif->drives[!(drive->dn%2)].id) { - if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) { - hwif->OUTB(CLKSPD | mask, (hwif->dma_master + 0x11)); - } else { - hwif->OUTB(CLKSPD & ~mask, (hwif->dma_master + 0x11)); - } - } else { /* udma4 drive by itself */ - hwif->OUTB(CLKSPD | mask, (hwif->dma_master + 0x11)); - } - } } + pdc_old_disable_66MHz_clock(drive->hwif); + drive_pci = 0x60 + (drive->dn << 2); pci_read_config_dword(dev, drive_pci, &drive_conf); if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) @@ -536,6 +526,8 @@ static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive) { + if (drive->current_speed > XFER_UDMA_2) + pdc_old_enable_66MHz_clock(drive->hwif); if (drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); @@ -569,6 +561,8 @@ clock = hwif->INB(high_16 + 0x11); hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11); } + if (drive->current_speed > XFER_UDMA_2) + pdc_old_disable_66MHz_clock(drive->hwif); return __ide_dma_end(drive); } @@ -757,10 +751,7 @@ hwif->speedproc = &pdc202xx_tune_chipset; - if (!hwif->dma_base) { - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - return; - } + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/siimage.c linux/drivers/ide/pci/siimage.c --- linux-2.6.0-test11/drivers/ide/pci/siimage.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/ide/pci/siimage.c 2003-12-08 00:33:51.712106272 +0100 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.06 June 11, 2003 + * linux/drivers/ide/pci/siimage.c Version 1.09 Dec 7, 2003 * * Copyright (C) 2001-2002 Andre Hedrick * Copyright (C) 2003 Red Hat @@ -56,6 +56,7 @@ { case PCI_DEVICE_ID_SII_3112: case PCI_DEVICE_ID_SII_1210SA: + case PCI_DEVICE_ID_SII_3114: return 1; case PCI_DEVICE_ID_SII_680: return 0; @@ -266,7 +267,7 @@ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) { ide_hwif_t *hwif = HWIF(drive); - u32 speedt = 0; + u16 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); unsigned long tfaddr = siimage_selreg(hwif, 0x02); @@ -1047,6 +1048,27 @@ hwif->mmio = 2; } +static int is_dev_seagate_sata(ide_drive_t *drive) +{ + const char *s = &drive->id->model[0]; + unsigned len; + + if (!drive->present) + return 0; + + len = strnlen(s, sizeof(drive->id->model)); + + if ((len > 4) && (!memcmp(s, "ST", 2))) { + if ((!memcmp(s + len - 2, "AS", 2)) || + (!memcmp(s + len - 3, "ASL", 3))) { + printk(KERN_INFO "%s: applying pessimistic Seagate " + "errata fix\n", drive->name); + return 1; + } + } + return 0; +} + /** * init_iops_siimage - set up iops * @hwif: interface to set up @@ -1068,7 +1090,7 @@ hwif->hwif_data = 0; hwif->rqsize = 128; - if (is_sata(hwif)) + if (is_sata(hwif) && is_dev_seagate_sata(&hwif->drives[0])) hwif->rqsize = 15; if (pci_get_drvdata(dev) == NULL) @@ -1179,6 +1201,7 @@ { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, { 0, }, }; diff -uNr -X exclude linux-2.6.0-test11/drivers/ide/pci/siimage.h linux/drivers/ide/pci/siimage.h --- linux-2.6.0-test11/drivers/ide/pci/siimage.h 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/ide/pci/siimage.h 2003-12-08 00:33:51.713106120 +0100 @@ -82,6 +82,16 @@ .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .bootable = ON_BOARD, .extra = 0, + },{ /* 3 */ + .vendor = PCI_VENDOR_ID_CMD, + .device = PCI_DEVICE_ID_SII_3114, + .name = "SiI3114 Serial ATA", + .init_chipset = init_chipset_siimage, + .init_iops = init_iops_siimage, + .init_hwif = init_hwif_siimage, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, },{ .vendor = 0, .device = 0, diff -uNr -X exclude linux-2.6.0-test11/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c --- linux-2.6.0-test11/drivers/net/pci-skeleton.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/net/pci-skeleton.c 2003-12-08 00:33:50.658266480 +0100 @@ -864,13 +864,6 @@ pci_release_regions (pdev); -#ifndef NETDRV_NDEBUG - /* poison memory before freeing */ - memset (dev, 0xBC, - sizeof (struct net_device) + - sizeof (struct netdrv_private)); -#endif /* NETDRV_NDEBUG */ - free_netdev (dev); pci_set_drvdata (pdev, NULL); diff -uNr -X exclude linux-2.6.0-test11/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c --- linux-2.6.0-test11/drivers/net/pcnet32.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/net/pcnet32.c 2003-12-08 00:33:50.667265112 +0100 @@ -1766,8 +1766,6 @@ next_dev = lp->next; unregister_netdev(pcnet32_dev); release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE); - if (lp->pci_dev) - pci_unregister_driver(&pcnet32_driver); pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); free_netdev(pcnet32_dev); pcnet32_dev = next_dev; diff -uNr -X exclude linux-2.6.0-test11/drivers/net/r8169.c linux/drivers/net/r8169.c --- linux-2.6.0-test11/drivers/net/r8169.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/net/r8169.c 2003-12-08 00:33:50.668264960 +0100 @@ -642,10 +642,6 @@ iounmap(tp->mmio_addr); pci_release_regions(pdev); - // poison memory before freeing - memset(dev, 0xBC, - sizeof (struct net_device) + sizeof (struct rtl8169_private)); - pci_disable_device(pdev); free_netdev(dev); pci_set_drvdata(pdev, NULL); diff -uNr -X exclude linux-2.6.0-test11/drivers/net/sis190.c linux/drivers/net/sis190.c --- linux-2.6.0-test11/drivers/net/sis190.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/net/sis190.c 2003-12-08 00:33:50.670264656 +0100 @@ -703,10 +703,6 @@ iounmap(tp->mmio_addr); pci_release_regions(pdev); - // poison memory before freeing - memset(dev, 0xBC, - sizeof (struct net_device) + sizeof (struct sis190_private)); - free_netdev(dev); pci_set_drvdata(pdev, NULL); } diff -uNr -X exclude linux-2.6.0-test11/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c --- linux-2.6.0-test11/drivers/scsi/ide-scsi.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/scsi/ide-scsi.c 2003-12-08 00:33:50.670264656 +0100 @@ -517,6 +517,7 @@ pc->current_position=pc->buffer; bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ + feature.all = 0; if (drive->using_dma && rq->bio) { if (test_bit(PC_WRITING, &pc->flags)) feature.b.dma = !HWIF(drive)->ide_dma_write(drive); diff -uNr -X exclude linux-2.6.0-test11/drivers/scsi/libata-core.c linux/drivers/scsi/libata-core.c --- linux-2.6.0-test11/drivers/scsi/libata-core.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/drivers/scsi/libata-core.c 2003-12-08 00:33:50.672264352 +0100 @@ -3224,8 +3224,6 @@ scsi_host_put(ap->host); /* FIXME: check return val */ } - kfree(host_set); - pci_release_regions(pdev); for (i = 0; i < host_set->n_ports; i++) { @@ -3242,6 +3240,7 @@ } } + kfree(host_set); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } diff -uNr -X exclude linux-2.6.0-test11/fs/proc/base.c linux/fs/proc/base.c --- linux-2.6.0-test11/fs/proc/base.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/fs/proc/base.c 2003-12-08 00:33:50.674264048 +0100 @@ -1666,10 +1666,14 @@ index -= 2; read_lock(&tasklist_lock); - do { + /* + * The starting point task (leader_task) might be an already + * unlinked task, which cannot be used to access the task-list + * via next_thread(). + */ + if (pid_alive(task)) do { int tid = task->pid; - if (!pid_alive(task)) - continue; + if (--index >= 0) continue; tids[nr_tids] = tid; diff -uNr -X exclude linux-2.6.0-test11/include/asm-x86_64/msr.h linux/include/asm-x86_64/msr.h --- linux-2.6.0-test11/include/asm-x86_64/msr.h 2003-12-08 00:29:13.000000000 +0100 +++ linux/include/asm-x86_64/msr.h 2003-12-08 00:33:50.674264048 +0100 @@ -50,9 +50,9 @@ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") #define rdtscll(val) do { \ - unsigned int a,d; \ - asm volatile("rdtsc" : "=a" (a), "=d" (d)); \ - (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \ + unsigned int __a,__d; \ + asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ + (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) #define rdpmc(counter,low,high) \ diff -uNr -X exclude linux-2.6.0-test11/include/linux/blkdev.h linux/include/linux/blkdev.h --- linux-2.6.0-test11/include/linux/blkdev.h 2003-12-08 00:29:13.000000000 +0100 +++ linux/include/linux/blkdev.h 2003-12-08 00:33:51.208182880 +0100 @@ -193,11 +193,6 @@ __REQ_PM_SUSPEND, /* suspend request */ __REQ_PM_RESUME, /* resume request */ __REQ_PM_SHUTDOWN, /* shutdown request */ - __REQ_IDETAPE_PC1, /* packet command (first stage) */ - __REQ_IDETAPE_PC2, /* packet command (second stage) */ - __REQ_IDETAPE_READ, - __REQ_IDETAPE_WRITE, - __REQ_IDETAPE_READ_BUFFER, __REQ_NR_BITS, /* stops here */ }; @@ -223,11 +218,6 @@ #define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND) #define REQ_PM_RESUME (1 << __REQ_PM_RESUME) #define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN) -#define REQ_IDETAPE_PC1 (1 << __REQ_IDETAPE_PC1) -#define REQ_IDETAPE_PC2 (1 << __REQ_IDETAPE_PC2) -#define REQ_IDETAPE_READ (1 << __REQ_IDETAPE_READ) -#define REQ_IDETAPE_WRITE (1 << __REQ_IDETAPE_WRITE) -#define REQ_IDETAPE_READ_BUFFER (1 << __REQ_IDETAPE_READ_BUFFER) /* * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME diff -uNr -X exclude linux-2.6.0-test11/include/linux/ide.h linux/include/linux/ide.h --- linux-2.6.0-test11/include/linux/ide.h 2003-12-08 00:29:12.000000000 +0100 +++ linux/include/linux/ide.h 2003-12-08 00:33:52.836935272 +0100 @@ -51,9 +51,6 @@ #ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */ #define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */ #endif -#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */ -#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ -#endif #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ #define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ #endif @@ -999,10 +996,6 @@ unsigned dma_extra; /* extra addr for dma ports */ unsigned long config_data; /* for use by chipset-specific code */ unsigned long select_data; /* for use by chipset-specific code */ -#if (DISK_RECOVERY_TIME > 0) - unsigned long last_time; /* time when previous rq was done */ -#endif - unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ diff -uNr -X exclude linux-2.6.0-test11/include/linux/pci_ids.h linux/include/linux/pci_ids.h --- linux-2.6.0-test11/include/linux/pci_ids.h 2003-12-08 00:29:13.000000000 +0100 +++ linux/include/linux/pci_ids.h 2003-12-08 00:33:51.715105816 +0100 @@ -882,6 +882,7 @@ #define PCI_DEVICE_ID_SII_680 0x0680 #define PCI_DEVICE_ID_SII_3112 0x3112 +#define PCI_DEVICE_ID_SII_3114 0x3114 #define PCI_DEVICE_ID_SII_1210SA 0x0240 #define PCI_VENDOR_ID_VISION 0x1098 diff -uNr -X exclude linux-2.6.0-test11/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h --- linux-2.6.0-test11/include/linux/rtnetlink.h 2003-12-08 00:29:13.000000000 +0100 +++ linux/include/linux/rtnetlink.h 2003-12-08 00:33:50.675263896 +0100 @@ -138,6 +138,7 @@ #define RTPROT_ZEBRA 11 /* Zebra */ #define RTPROT_BIRD 12 /* BIRD */ #define RTPROT_DNROUTED 13 /* DECnet routing daemon */ +#define RTPROT_XORP 14 /* XORP */ /* rtm_scope diff -uNr -X exclude linux-2.6.0-test11/kernel/sched.c linux/kernel/sched.c --- linux-2.6.0-test11/kernel/sched.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/kernel/sched.c 2003-12-08 00:33:50.677263592 +0100 @@ -646,7 +646,7 @@ */ p->activated = -1; } - if (sync) + if (sync && (task_cpu(p) == smp_processor_id())) __activate_task(p, rq); else { activate_task(p, rq); diff -uNr -X exclude linux-2.6.0-test11/Makefile linux/Makefile --- linux-2.6.0-test11/Makefile 2003-12-08 00:29:13.000000000 +0100 +++ linux/Makefile 2003-12-08 00:33:50.842238512 +0100 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -test11 +EXTRAVERSION = -test11-bk5-bart1 # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -uNr -X exclude linux-2.6.0-test11/mm/mmap.c linux/mm/mmap.c --- linux-2.6.0-test11/mm/mmap.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/mm/mmap.c 2003-12-08 00:33:50.680263136 +0100 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -474,8 +475,13 @@ struct rb_node ** rb_link, * rb_parent; unsigned long charged = 0; - if (file && (!file->f_op || !file->f_op->mmap)) - return -ENODEV; + if (file) { + if (!file->f_op || !file->f_op->mmap) + return -ENODEV; + + if ((prot & PROT_EXEC) && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)) + return -EPERM; + } if (!len) return addr; diff -uNr -X exclude linux-2.6.0-test11/net/bridge/br_netfilter.c linux/net/bridge/br_netfilter.c --- linux-2.6.0-test11/net/bridge/br_netfilter.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/net/bridge/br_netfilter.c 2003-12-08 00:33:50.681262984 +0100 @@ -180,7 +180,7 @@ struct rtable *rt; struct flowi fl = { .nl_u = { .ip4_u = { .daddr = iph->daddr, .saddr = 0 , - .tos = iph->tos} }, .proto = 0}; + .tos = RT_TOS(iph->tos)} }, .proto = 0}; if (!ip_route_output_key(&rt, &fl)) { /* Bridged-and-DNAT'ed traffic doesn't diff -uNr -X exclude linux-2.6.0-test11/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- linux-2.6.0-test11/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-12-08 00:33:50.681262984 +0100 @@ -53,7 +53,7 @@ unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS; unsigned long ip_ct_tcp_timeout_established = 5 DAYS; unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS; -unsigned long ip_ct_tcp_timeout_close_wait = 3 DAYS; +unsigned long ip_ct_tcp_timeout_close_wait = 60 SECS; unsigned long ip_ct_tcp_timeout_last_ack = 30 SECS; unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS; unsigned long ip_ct_tcp_timeout_close = 10 SECS; diff -uNr -X exclude linux-2.6.0-test11/net/ipv4/netfilter/ip_conntrack_standalone.c linux/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.6.0-test11/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-12-08 00:33:50.682262832 +0100 @@ -201,7 +201,8 @@ /* Local packets are never produced too large for their interface. We degfragment them at LOCAL_OUT, however, so we have to refragment them here. */ - if ((*pskb)->len > dst_pmtu(&rt->u.dst)) { + if ((*pskb)->len > dst_pmtu(&rt->u.dst) && + !skb_shinfo(*pskb)->tso_size) { /* No hook can be after us, so this should be OK. */ ip_fragment(*pskb, okfn); return NF_STOLEN; diff -uNr -X exclude linux-2.6.0-test11/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- linux-2.6.0-test11/net/ipv4/tcp_ipv4.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/net/ipv4/tcp_ipv4.c 2003-12-08 00:33:50.684262528 +0100 @@ -2356,6 +2356,7 @@ static void *tcp_seq_start(struct seq_file *seq, loff_t *pos) { struct tcp_iter_state* st = seq->private; + st->state = TCP_SEQ_STATE_LISTENING; st->num = 0; return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; } diff -uNr -X exclude linux-2.6.0-test11/net/ipv6/udp.c linux/net/ipv6/udp.c --- linux-2.6.0-test11/net/ipv6/udp.c 2003-12-08 00:29:13.000000000 +0100 +++ linux/net/ipv6/udp.c 2003-12-08 00:33:50.685262376 +0100 @@ -825,7 +825,7 @@ struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = sin6 ? sin6->sin6_port : inet->dport; - sin.sin_addr.s_addr = daddr->s6_addr[3]; + sin.sin_addr.s_addr = daddr->s6_addr32[3]; msg->msg_name = &sin; msg->msg_namelen = sizeof(sin); do_udp_sendmsg: