From bb58596f6802a4959c2cea02acd272245e671c1d Mon Sep 17 00:00:00 2001 From: Dave C Boutcher Date: Tue, 15 Nov 2005 09:53:00 -0600 Subject: [PATCH 01/91] [SCSI] ibmvscsi kexec fix This makes ibmvscsi work correctly with the recent set of kexec patches that went in. This is based on work by Michael Ellerman, who chased this initially. He validated that it works during kexec. Handle kexec correctly in ibmvscsi. During kexec the adapter will not get cleaned up correctly, so we may need to reset it to make it sane again. Signed-off-by: Dave Boutcher Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvscsi.h | 2 +- drivers/scsi/ibmvscsi/iseries_vscsi.c | 3 ++- drivers/scsi/ibmvscsi/rpa_vscsi.c | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 8bec0438dc8a..5b0edd1f1921 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -100,7 +100,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, void ibmvscsi_release_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata, int max_requests); -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata); void ibmvscsi_handle_crq(struct viosrp_crq *crq, diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 1045872b0175..ce15d9e39621 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -117,9 +117,10 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { + return 0; } /** diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 8bf5652f1060..75db2f5c545e 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -230,6 +230,11 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); + if (rc == H_Resource) + /* maybe kexecing and resource is busy. try a reset */ + rc = ibmvscsi_reset_crq_queue(queue, + hostdata); + if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); @@ -281,7 +286,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, * @hostdata: ibmvscsi_host_data of host * */ -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc; @@ -309,4 +314,5 @@ void ibmvscsi_reset_crq_queue(struct crq_queue *queue, printk(KERN_WARNING "ibmvscsi: couldn't register crq--rc 0x%x\n", rc); } + return rc; } From 23443b1d6130eff8e1335e4f84eaf0577a331dcf Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 6 Dec 2005 10:57:06 -0800 Subject: [PATCH 02/91] [SCSI] qla2xxx: Correct mis-handling of AENs. A regression in a recent change 33135aa2a568ec1a30e734f18e5315e10516e4f3 caused the driver to mistakenly drop handling of AENs. Due to the incorrect handling, ports would not reappear after RSCNs and LIPs. Drops unused/incorrect compound #define from qla_def.h. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 10 +--------- drivers/scsi/qla2xxx/qla_init.c | 6 +++--- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7096945ea234..7b3efd531297 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2476,17 +2476,9 @@ typedef struct scsi_qla_host { */ #define LOOP_TRANSITION(ha) \ (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) - -#define LOOP_NOT_READY(ha) \ - ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \ - test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) || \ + test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ atomic_read(&ha->loop_state) == LOOP_DOWN) -#define LOOP_RDY(ha) (!LOOP_NOT_READY(ha)) - #define TGT_Q(ha, t) (ha->otgt[t]) #define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 2d720121a0d3..c46d2469b85f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1259,7 +1259,7 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa, &area, &domain, &topo); if (rval != QLA_SUCCESS) { - if (LOOP_NOT_READY(ha) || atomic_read(&ha->loop_down_timer) || + if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) || (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) { DEBUG2(printk("%s(%ld) Loop is in a transition state\n", __func__, ha->host_no)); @@ -1796,7 +1796,7 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) } if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) { - if (LOOP_NOT_READY(ha)) { + if (LOOP_TRANSITION(ha)) { rval = QLA_FUNCTION_FAILED; } else { rval = qla2x00_configure_fabric(ha); @@ -2369,7 +2369,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) if (qla2x00_is_reserved_id(ha, loop_id)) continue; - if (atomic_read(&ha->loop_down_timer) || LOOP_NOT_READY(ha)) + if (atomic_read(&ha->loop_down_timer) || LOOP_TRANSITION(ha)) break; if (swl != NULL) { From 0da69df1e54146eece38e0a144051f6dd3526821 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 6 Dec 2005 10:58:06 -0800 Subject: [PATCH 03/91] [SCSI] qla2xxx: Correct short-WRITE status handling. Properly check FC_RESID for any non-transfered bytes regardless of firmware completion status. Signed-off-by: Andrew Vasquez Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_isr.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 09afc0f06bd4..5181d966fecb 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -909,6 +909,21 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) resid = resid_len; cp->resid = resid; CMD_RESID_LEN(cp) = resid; + + if (!lscsi_status && + ((unsigned)(cp->request_bufflen - resid) < + cp->underflow)) { + qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Mid-layer underflow " + "detected (%x of %x bytes)...returning " + "error status.\n", ha->host_no, + cp->device->channel, cp->device->id, + cp->device->lun, resid, + cp->request_bufflen); + + cp->result = DID_ERROR << 16; + break; + } } cp->result = DID_OK << 16 | lscsi_status; From f0353301e6752399ceb874ede7f44e3571c5e4f3 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 7 Dec 2005 17:46:57 -0500 Subject: [PATCH 04/91] [SCSI] Fix incorrect pointer in megaraid.c MODE_SENSE emulation The SCSI megaraid drive goes to great effort to kmap the scatterlist buffer (if used), but then uses the wrong pointer when copying to it afterward. Signed-off-by: Mark Lord Acked by: Ju, Seokmann Signed-off-by: James Bottomley --- drivers/scsi/megaraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index f9792528e33f..578143e93a6f 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -664,7 +664,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) sg->offset; } else buf = cmd->request_buffer; - memset(cmd->request_buffer, 0, cmd->cmnd[4]); + memset(buf, 0, cmd->cmnd[4]); if (cmd->use_sg) { struct scatterlist *sg; From 85631672e6a8032267058b4ccbe53f1924a5d0be Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Wed, 7 Dec 2005 21:46:27 -0600 Subject: [PATCH 05/91] [SCSI] fix OOPS due to clearing eh_action prior to aborting eh command The eh_action semaphore in scsi_eh_send_command is cleared after a command timeout. The command is subsequently aborted and the abort will try to call scsi_done() on it. Unfortunately, the scsi_eh_done() routine unconditinally completes the semaphore (which is now null). Fix this race by makiong the scsi_eh_done() routine check that the semaphore is non null before completing it (mirroring the ordinary command done/timeout logic). Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 18c5d2523014..c0ae9e965f6f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -422,10 +422,15 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) **/ static void scsi_eh_done(struct scsi_cmnd *scmd) { + struct completion *eh_action; + SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n", __FUNCTION__, scmd, scmd->result)); - complete(scmd->device->host->eh_action); + + eh_action = scmd->device->host->eh_action; + if (eh_action) + complete(eh_action); } /** From a8c730e85e80734412f4f73ab28496a0e8b04a7b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 9 Dec 2005 14:42:16 +0100 Subject: [PATCH 06/91] [SCSI] fix panic when ejecting ieee1394 ipod The scsi_library routines don't correctly set DMA_NONE when req->data_len is zero (instead they check the command type first, so if it's write, we end up with req->data_len == 0 and direction as DMA_TO_DEVICE which confuses some drivers) Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4afef5cdcb17..097888721ec4 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1215,12 +1215,12 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) } else { memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); cmd->cmd_len = req->cmd_len; - if (rq_data_dir(req) == WRITE) - cmd->sc_data_direction = DMA_TO_DEVICE; - else if (req->data_len) - cmd->sc_data_direction = DMA_FROM_DEVICE; - else + if (!req->data_len) cmd->sc_data_direction = DMA_NONE; + else if (rq_data_dir(req) == WRITE) + cmd->sc_data_direction = DMA_TO_DEVICE; + else + cmd->sc_data_direction = DMA_FROM_DEVICE; cmd->transfersize = req->data_len; cmd->allowed = 3; From 1ee9530a71686436dbeb5f31dd5b925c39cf71d7 Mon Sep 17 00:00:00 2001 From: Lothar Wassmann Date: Mon, 12 Dec 2005 16:44:05 +0000 Subject: [PATCH 07/91] [ARM] 3201/1: PXA27x: Prevent hangup during resume due to inadvertedly enabling MBREQ (replaces: 3198/1) Patch from Lothar Wassmann The patch makes sure, that the ouptut functions of pins are restored before restoring the Alternat Function settings, preventing pins from being intermediately configured for undefined or unwanted alternate functions. Here is the original comment: I've got a PXA270 system that uses GPIO80 as nCS4. This system did hang on resume. Digging into the problem I found that the processor stalled immediately when restoring the GAFR2_U register which restored the alternate function for GPIO80. Since the GPDR registers were restored after the GAFR registers, the offending GPIO was configured as input at this point. Thus the alternate function that was in effect after restoring the GAFR was in fact the input function "MBREQ" instead of the output function "nCS4". The "PXA27x Processor Family Developer's Manual" (Footnote in Table 6-1 on page 6-3) states that: "The MBREQ alternate function must not be enabled until the PSSR[RDH] bit field is cleared. For more details, see Table 3-15, "PSSR Bit Definitions" on page 3-71." There is another note in the Developer's Manual (chapter 24.4.2 "GPIO operation as Alternate Function" on page 24-4) stating that: "Configuring a GPIO for an alternate function that is not defined for it causes unpredictable results." Since some GPIOs have no input function defined, and to prevent inadvertedly programming the MBREQ function on some pin, the GAFR registers should be restored after the GPDR registers have been restored. Additional provisions have to be made when the MBREQ function is actually required. The corresponding GAFR bits should not be restored with the regular GAFR restore, but must be set only after the PSSR bits have been cleared. Signed-off-by: Lothar Wassmann Signed-off-by: Russell King --- arch/arm/mach-pxa/pm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index f74b9af112dc..852ea72d8c80 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -155,19 +155,20 @@ int pxa_pm_enter(suspend_state_t state) PSPR = 0; /* restore registers */ + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GAFR0_L); RESTORE(GAFR0_U); RESTORE(GAFR1_L); RESTORE(GAFR1_U); RESTORE(GAFR2_L); RESTORE(GAFR2_U); - RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); - RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); #ifdef CONFIG_PXA27x RESTORE(MDREFR); - RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); - RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); + RESTORE_GPLEVEL(3); RESTORE(GPDR3); + RESTORE(GAFR3_L); RESTORE(GAFR3_U); + RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); RESTORE(PFER); RESTORE(PKWR); #endif From 1a68de5c08be8c77c4ad208306187bd95107c7cd Mon Sep 17 00:00:00 2001 From: Brian King Date: Mon, 12 Dec 2005 13:05:08 -0600 Subject: [PATCH 08/91] [SCSI] fix double free of scsi request queue Current scsi scanning code appears to have a use after free bug is a LLDD's slave_alloc fails. Remove the redundant scsi_free_queue. Signed-off-by: Brian King Signed-off-by: James Bottomley --- drivers/scsi/scsi_scan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 374853df9cca..be276ea8f033 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -279,7 +279,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, out_device_destroy: transport_destroy_device(&sdev->sdev_gendev); - scsi_free_queue(sdev->request_queue); put_device(&sdev->sdev_gendev); out: if (display_failure_msg) From 322e079f1b606e46b79bb8b8e6cf6110b5f2aa3f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 29 Nov 2005 23:08:40 -0500 Subject: [PATCH 09/91] [SCSI] Negotiate correctly with async-only devices When we got a device only capable of async, we would zero out goal->period which would cause us to try PPR negotiations. Leave goal->period alone, and check goal->offset before doing PPR. Kudos to Daniel Forsgren for figuring this out. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/sym53c8xx_2/sym_hipd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index a7420cad4547..1564ca203a3e 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -1405,7 +1405,6 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget, goal->iu = 0; goal->dt = 0; goal->qas = 0; - goal->period = 0; goal->offset = 0; return; } @@ -1465,7 +1464,8 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp * Many devices implement PPR in a buggy way, so only use it if we * really want to. */ - if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) { + if (goal->offset && + (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) { nego = NS_PPR; } else if (spi_width(starget) != goal->width) { nego = NS_WIDE; From 381291b7d3e17ac966498312dc571dcca1b93efc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:08:21 -0800 Subject: [PATCH 10/91] [TG3]: Fix nvram arbitration bugs. The nvram arbitration rules were not strictly followed in a few places and this could lead to reading corrupted values from the nvram. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 47bd4a394420..dabc39befd3c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8533,6 +8533,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { tp->tg3_flags |= TG3_FLAG_NVRAM; + tg3_nvram_lock(tp); tg3_enable_nvram_access(tp); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) @@ -8543,6 +8544,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) tg3_get_nvram_size(tp); tg3_disable_nvram_access(tp); + tg3_nvram_unlock(tp); } else { tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED); @@ -8640,10 +8642,10 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) if (ret == 0) *val = swab32(tr32(NVRAM_RDDATA)); - tg3_nvram_unlock(tp); - tg3_disable_nvram_access(tp); + tg3_nvram_unlock(tp); + return ret; } @@ -8728,6 +8730,10 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, offset = offset + (pagesize - page_off); + /* Nvram lock released by tg3_nvram_read() above, + * so need to get it again. + */ + tg3_nvram_lock(tp); tg3_enable_nvram_access(tp); /* From 6a9eba15f51c56da637e45ea1316eaa2a848986a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:08:58 -0800 Subject: [PATCH 11/91] [TG3]: Fix suspend and resume Fix tg3_suspend() and tg3_resume() by clearing and setting the TG3_FLAG_INIT_COMPLETE flag when appropriate. tg3_set_power_state() looks at TG3_FLAG_INIT_COMPLETE on the peer device to determine when to appropriately switch to aux power. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index dabc39befd3c..6b7ab4b72752 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10826,12 +10826,14 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tg3_full_lock(tp, 0); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; tg3_full_unlock(tp); err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); if (err) { tg3_full_lock(tp, 0); + tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tg3_init_hw(tp); tp->timer.expires = jiffies + tp->timer_offset; @@ -10865,6 +10867,7 @@ static int tg3_resume(struct pci_dev *pdev) tg3_full_lock(tp, 0); + tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; tg3_init_hw(tp); tp->timer.expires = jiffies + tp->timer_offset; From 16fe9d74f14ed74af778c5db7f9129e29916f4a7 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:09:54 -0800 Subject: [PATCH 12/91] [TG3]: Fix 5704 single-port mode If the dual-port 5704 is configured as a single-port device with only one PCI function, it would trigger a BUG() condition in tg3_find_5704_peer(). This fixes the problem by returning its own pdev if the peer cannot be found. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6b7ab4b72752..a143c18c7bc6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10443,8 +10443,13 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) break; pci_dev_put(peer); } - if (!peer || peer == tp->pdev) - BUG(); + /* 5704 can be configured in single-port mode, set peer to + * tp->pdev in that case. + */ + if (!peer) { + peer = tp->pdev; + return peer; + } /* * We don't need to keep the refcount elevated; there's no way From 6921d201f77e14848df2eaa597e26525f468abea Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:15:53 -0800 Subject: [PATCH 13/91] [TG3]: Fix low power state Fix the following bugs in tg3_set_power_state(): 1. Both WOL and ASF flags require switching to aux power. 2. Add a missing handshake with firmware to enable WOL. 3. Turn off the PHY if both WOL and ASF are disabled. 4. Add nvram arbitration before halting the firmware. 5. Fix tg3_setup_copper_phy() to switch to 100Mbps when changing to low power state. Update revision and date. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 44 +++++++++++++++++++++++++++++++++++++++----- drivers/net/tg3.h | 7 +++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index a143c18c7bc6..a23ed28a72b8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.44" -#define DRV_MODULE_RELDATE "Dec 6, 2005" +#define DRV_MODULE_VERSION "3.45" +#define DRV_MODULE_RELDATE "Dec 13, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -1025,7 +1025,9 @@ static void tg3_frob_aux_power(struct tg3 *tp) if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || - (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) { + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 || + (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 || + (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) { tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl | @@ -1105,6 +1107,8 @@ static int tg3_setup_phy(struct tg3 *, int); static void tg3_write_sig_post_reset(struct tg3 *, int); static int tg3_halt_cpu(struct tg3 *, u32); +static int tg3_nvram_lock(struct tg3 *); +static void tg3_nvram_unlock(struct tg3 *); static int tg3_set_power_state(struct tg3 *tp, int state) { @@ -1179,6 +1183,21 @@ static int tg3_set_power_state(struct tg3 *tp, int state) tg3_setup_phy(tp, 0); } + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + int i; + u32 val; + + for (i = 0; i < 200; i++) { + tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + msleep(1); + } + } + tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | + WOL_DRV_STATE_SHUTDOWN | + WOL_DRV_WOL | WOL_SET_MAGIC_PKT); + pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { @@ -1268,6 +1287,17 @@ static int tg3_set_power_state(struct tg3 *tp, int state) } } + if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) && + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + /* Turn off the PHY */ + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + tg3_writephy(tp, MII_TG3_EXT_CTRL, + MII_TG3_EXT_CTRL_FORCE_LED_OFF); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); + tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); + } + } + tg3_frob_aux_power(tp); /* Workaround for unstable PLL clock */ @@ -1277,8 +1307,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state) val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); tw32(0x7d00, val); - if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + tg3_nvram_lock(tp); tg3_halt_cpu(tp, RX_CPU_BASE); + tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0); + tg3_nvram_unlock(tp); + } } /* Finally, set the new power state. */ @@ -1812,7 +1846,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) } } relink: - if (current_link_up == 0) { + if (current_link_up == 0 || tp->link_config.phy_is_low_power) { u32 tmp; tg3_phy_copper_begin(tp); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index fb7e2a5f4a08..94dbcf3537ec 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1529,6 +1529,12 @@ #define NIC_SRAM_MAC_ADDR_HIGH_MBOX 0x00000c14 #define NIC_SRAM_MAC_ADDR_LOW_MBOX 0x00000c18 +#define NIC_SRAM_WOL_MBOX 0x00000d30 +#define WOL_SIGNATURE 0x474c0000 +#define WOL_DRV_STATE_SHUTDOWN 0x00000001 +#define WOL_DRV_WOL 0x00000002 +#define WOL_SET_MAGIC_PKT 0x00000004 + #define NIC_SRAM_DATA_CFG_2 0x00000d38 #define SHASTA_EXT_LED_MODE_MASK 0x00018000 @@ -1565,6 +1571,7 @@ #define MII_TG3_EXT_CTRL 0x10 /* Extended control register */ #define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001 #define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002 +#define MII_TG3_EXT_CTRL_FORCE_LED_OFF 0x0008 #define MII_TG3_EXT_CTRL_TBI 0x8000 #define MII_TG3_EXT_STAT 0x11 /* Extended status register */ From 664d22ab954de54e52e0f71103a89c7a78738adc Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Tue, 13 Dec 2005 17:03:36 -0800 Subject: [PATCH 14/91] [PATCH] Dmitry Torokhov is input subsystem maintainer I haven't been very actively maintaining the input layer in past months, mostly because of my lack of time to concentrate on that. For that reason, I've decided to pass the maintainership of the Linux Input Layer to Dmitry Torokhov, whom I trust to do the job very well. Signed-off-by: Vojtech Pavlik Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 77bb08606912..da6973adacda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1284,8 +1284,8 @@ T: git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git S: Supported INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS -P: Vojtech Pavlik -M: vojtech@suse.cz +P: Dmitry Torokhov +M: dtor_core@ameritech.net L: linux-input@atrey.karlin.mff.cuni.cz L: linux-joystick@atrey.karlin.mff.cuni.cz T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git From 118c71bcacce82a4317c9bd99c6a15af14020aee Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Tue, 13 Dec 2005 17:03:37 -0800 Subject: [PATCH 15/91] [PATCH] Fix calculation of grow_pgdat_span() in mm/memory_hotplug.c The calculation for node_spanned_pages at grow_pgdat_span() is clearly wrong. This is patch for it. (Please see grow_zone_span() to compare. It is correct.) Signed-off-by: Yasunori Goto Acked-by: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory_hotplug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 431a64f021c0..f6d4af8af8a8 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -104,7 +104,7 @@ static void grow_pgdat_span(struct pglist_data *pgdat, pgdat->node_start_pfn = start_pfn; if (end_pfn > old_pgdat_end_pfn) - pgdat->node_spanned_pages = end_pfn - pgdat->node_spanned_pages; + pgdat->node_spanned_pages = end_pfn - pgdat->node_start_pfn; } int online_pages(unsigned long pfn, unsigned long nr_pages) From fb79ffa4ddbe3f6f30fdb8429b5bad84d25ae6ef Mon Sep 17 00:00:00 2001 From: Ole Reinhardt Date: Tue, 13 Dec 2005 17:03:38 -0800 Subject: [PATCH 16/91] [PATCH] fbdev: make pxafb more robust to errors with CONFIG_FB_PXA_PARAMETERS pxafb.c runs into an oops if CONFIG_FB_PXA_PARAMETERS is enabled and no parameters are set in command line. The following patch avoids this problem. Signed-off-by: Nicolas Pitre Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/pxafb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 7b4cd250bec8..9fc10b9e6f57 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1396,7 +1396,8 @@ static struct platform_driver pxafb_driver = { int __devinit pxafb_setup(char *options) { # ifdef CONFIG_FB_PXA_PARAMETERS - strlcpy(g_options, options, sizeof(g_options)); + if (options) + strlcpy(g_options, options, sizeof(g_options)); # endif return 0; } From cd6104572bca9e4afe0dcdb8ecd65ef90b01297b Mon Sep 17 00:00:00 2001 From: Adam Kropelin Date: Tue, 13 Dec 2005 17:03:39 -0800 Subject: [PATCH 17/91] [PATCH] hid-core: Zero-pad truncated reports When it detects a truncated report, hid-core emits a warning and then processes the report as usual. This is good because it allows buggy devices to still get data thru to userspace. However, the missing bytes of the report should be cleared before processing, otherwise userspace will be handed partially-uninitialized data. This fixes Debian tracker bug #330487. Signed-off-by: Adam Kropelin Cc: Vojtech Pavlik Acked-by: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/usb/input/hid-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 45f3130fadea..a3e44ef1df43 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -893,8 +893,10 @@ static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_ size = ((report->size - 1) >> 3) + 1; - if (len < size) + if (len < size) { dbg("report %d is too short, (%d < %d)", report->id, len, size); + memset(data + len, 0, size - len); + } if (hid->claimed & HID_CLAIMED_HIDDEV) hiddev_report_event(hid, report); From c9526497cf03ee775c3a6f8ba62335735f98de7a Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 9 Dec 2005 17:45:22 -0500 Subject: [PATCH 18/91] [SCSI] Consolidate REQ_BLOCK_PC handling path (fix ipod panic) This follows on from Jens' patch and consolidates all of the ULD separate handlers for REQ_BLOCK_PC into a single call which has his fix for our direction bug. Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 33 +++++++++++++++++++++------------ drivers/scsi/sd.c | 16 +--------------- drivers/scsi/sr.c | 20 +++----------------- drivers/scsi/st.c | 19 +------------------ include/scsi/scsi_cmnd.h | 1 + 5 files changed, 27 insertions(+), 62 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 097888721ec4..9be5769d44aa 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1078,6 +1078,26 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0); } +void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries) +{ + struct request *req = cmd->request; + + BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); + cmd->cmd_len = req->cmd_len; + if (!req->data_len) + cmd->sc_data_direction = DMA_NONE; + else if (rq_data_dir(req) == WRITE) + cmd->sc_data_direction = DMA_TO_DEVICE; + else + cmd->sc_data_direction = DMA_FROM_DEVICE; + + cmd->transfersize = req->data_len; + cmd->allowed = retries; + cmd->timeout_per_command = req->timeout; +} +EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd); + static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q->queuedata; @@ -1213,18 +1233,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) goto kill; } } else { - memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); - cmd->cmd_len = req->cmd_len; - if (!req->data_len) - cmd->sc_data_direction = DMA_NONE; - else if (rq_data_dir(req) == WRITE) - cmd->sc_data_direction = DMA_TO_DEVICE; - else - cmd->sc_data_direction = DMA_FROM_DEVICE; - - cmd->transfersize = req->data_len; - cmd->allowed = 3; - cmd->timeout_per_command = req->timeout; + scsi_setup_blk_pc_cmnd(cmd, 3); cmd->done = scsi_generic_done; } } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8613a1317712..03fcbab30033 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -245,24 +245,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * SG_IO from block layer already setup, just copy cdb basically */ if (blk_pc_request(rq)) { - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; - - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else if (rq->data_len) - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - else - SCpnt->sc_data_direction = DMA_NONE; - - this_count = rq->data_len; + scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES); if (rq->timeout) timeout = rq->timeout; - SCpnt->transfersize = rq->data_len; - SCpnt->allowed = SD_PASSTHROUGH_RETRIES; goto queue; } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d68cea753bb2..fb4012b5c188 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -320,25 +320,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) * these are already setup, just copy cdb basically */ if (SCpnt->request->flags & REQ_BLOCK_PC) { - struct request *rq = SCpnt->request; + scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES); - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; + if (SCpnt->timeout_per_command) + timeout = SCpnt->timeout_per_command; - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - if (!rq->data_len) - SCpnt->sc_data_direction = DMA_NONE; - else if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - - this_count = rq->data_len; - if (rq->timeout) - timeout = rq->timeout; - - SCpnt->transfersize = rq->data_len; goto queue; } diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 7ac6ea141fff..dd592f6a2529 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4194,27 +4194,10 @@ static void st_intr(struct scsi_cmnd *SCpnt) */ static int st_init_command(struct scsi_cmnd *SCpnt) { - struct request *rq; - if (!(SCpnt->request->flags & REQ_BLOCK_PC)) return 0; - rq = SCpnt->request; - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; - - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - - if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else if (rq->data_len) - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - else - SCpnt->sc_data_direction = DMA_NONE; - - SCpnt->timeout_per_command = rq->timeout; - SCpnt->transfersize = rq->data_len; + scsi_setup_blk_pc_cmnd(SCpnt, 0); SCpnt->done = st_intr; return 1; } diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 7529f4388bb4..20da282d4abb 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -151,5 +151,6 @@ extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t); extern void scsi_put_command(struct scsi_cmnd *); extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); extern void scsi_finish_command(struct scsi_cmnd *cmd); +extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries); #endif /* _SCSI_SCSI_CMND_H */ From a1493d9cd1aaed06860d128a37df1bdfbc61f7c8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Dec 2005 22:59:36 -0800 Subject: [PATCH 19/91] [IPV6] addrconf: Do not print device pointer in privacy log message. Noticed by Andi Kleen, it is pointless to emit the device structure pointer in the kernel logs like this. Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 76ff9f4fe89d..73a23b4130a5 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -379,8 +379,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) dev->type == ARPHRD_NONE || dev->type == ARPHRD_SIT) { printk(KERN_INFO - "Disabled Privacy Extensions on device %p(%s)\n", - dev, dev->name); + "%s: Disabled Privacy Extensions\n", + dev->name); ndev->cnf.use_tempaddr = -1; } else { in6_dev_hold(ndev); From 2edc2689f8183dd21c45621a01580b340ac420ba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Dec 2005 22:59:50 -0800 Subject: [PATCH 20/91] [PKT_SCHED]: Disable debug tracing logs by default in packet action API. Noticed by Andi Kleen. Signed-off-by: David S. Miller --- net/sched/act_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 8aebe8f6d271..2ce1cb2aa2ed 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -34,7 +34,7 @@ #include #include -#if 1 /* control */ +#if 0 /* control */ #define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args) #else #define DPRINTK(format, args...) From 45f8245b972e360c19aec9032e2a2033b8ac3719 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 14 Dec 2005 14:57:35 +0000 Subject: [PATCH 21/91] [MMC] Explain the internals of mmc_power_up() It seems that people get confused about what is happening in mmc_power_up(). Add a comment to make it clear why we have a two stage process. Signed-off-by: Russell King --- drivers/mmc/mmc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index b586a83a9b4c..eb41391e06e9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -679,7 +679,15 @@ static void mmc_idle_cards(struct mmc_host *host) } /* - * Apply power to the MMC stack. + * Apply power to the MMC stack. This is a two-stage process. + * First, we enable power to the card without the clock running. + * We then wait a bit for the power to stabilise. Finally, + * enable the bus drivers and clock to the card. + * + * We must _NOT_ enable the clock prior to power stablising. + * + * If a host does all the power sequencing itself, ignore the + * initial MMC_POWER_UP stage. */ static void mmc_power_up(struct mmc_host *host) { From 27af4cfd11883073359bd5acab1962b0fa96a3bf Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Wed, 14 Dec 2005 06:58:05 -0600 Subject: [PATCH 22/91] [IA64] fix for SET_PERSONALITY when CONFIG_IA32_SUPPORT is not set. Missed this when fixing the SET_PERSONALITY change. Signed-off-by: Robin Holt Signed-off-by: Tony Luck --- arch/ia64/kernel/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index a4da715a360c..e9904c74d2ba 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -721,11 +721,13 @@ flush_thread (void) /* drop floating-point and debug-register state if it exists: */ current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); ia64_drop_fpu(current); +#ifdef CONFIG_IA32_SUPPORT if (IS_IA32_PROCESS(ia64_task_regs(current))) { ia32_drop_partial_page_list(current); current->thread.task_size = IA32_PAGE_OFFSET; set_fs(USER_DS); } +#endif } /* From 1542272a60ab9c0655a13ead8b7d7a661365f9fb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Dec 2005 12:55:24 -0800 Subject: [PATCH 23/91] [GRE]: Fix hardware checksum modification The skb_postpull_rcsum introduced a bug to the checksum modification. Although the length pulled is offset bytes, the origin of the pulling is the GRE header, not the IP header. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a4c347c3b8e3..46f9d9cf7a5f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -618,7 +618,7 @@ static int ipgre_rcv(struct sk_buff *skb) skb->mac.raw = skb->nh.raw; skb->nh.raw = __pskb_pull(skb, offset); - skb_postpull_rcsum(skb, skb->mac.raw, offset); + skb_postpull_rcsum(skb, skb->h.raw, offset); memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->pkt_type = PACKET_HOST; #ifdef CONFIG_NET_IPGRE_BROADCAST From c2e2611425a956d25d2948c5d95d3848c4db1257 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 14 Dec 2005 22:04:22 +0000 Subject: [PATCH 24/91] [ARM] 3205/1: Handle new EABI relocations when loading kernel modules. Patch from Daniel Jacobowitz Handle new EABI relocations when loading kernel modules. This is necessary for CONFIG_AEABI kernels, and also for some broken (since fixed) old ABI toolchains. Signed-off-by: Daniel Jacobowitz Signed-off-by: Russell King --- arch/arm/kernel/module.c | 2 ++ include/asm-arm/elf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 6055e1427ba3..055bf5d28894 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -101,6 +101,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, break; case R_ARM_PC24: + case R_ARM_CALL: + case R_ARM_JUMP24: offset = (*(u32 *)loc & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h index 7da97a937548..2d44b42d1847 100644 --- a/include/asm-arm/elf.h +++ b/include/asm-arm/elf.h @@ -22,6 +22,8 @@ typedef unsigned long elf_freg_t[3]; #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS32 2 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) typedef elf_greg_t elf_gregset_t[ELF_NGREG]; From a388442c3798a345d131ff8b9d6dea0bfda3fefc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 14 Dec 2005 16:23:16 -0800 Subject: [PATCH 25/91] [VLAN]: Fix hardware rx csum errors Receiving VLAN packets over a device (without VLAN assist) that is doing hardware checksumming (CHECKSUM_HW), causes errors because the VLAN code forgets to adjust the hardware checksum. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b74864889670..f2a8750bbf1d 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -165,6 +165,9 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, skb_pull(skb, VLAN_HLEN); /* take off the VLAN header (4 bytes currently) */ + /* Need to correct hardware checksum */ + skb_postpull_rcsum(skb, vhdr, VLAN_HLEN); + /* Ok, lets check to make sure the device (dev) we * came in on is what this VLAN is attached to. */ From deb5e5c0c68e59b1bf9ede66da9e6a89f6557595 Mon Sep 17 00:00:00 2001 From: Jeremy Higdon Date: Thu, 15 Dec 2005 02:10:35 +0100 Subject: [PATCH 26/91] [PATCH] sgiioc4: check for no hwifs available Add a check to the sgiioc4 driver for the case where all available ide_hwifs structures are in use. Signed-off-by: Jeremy Higdon Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sgiioc4.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index af526b671c4e..4ee597d08797 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -622,12 +622,18 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) ide_hwif_t *hwif; int h; + /* + * Find an empty HWIF; if none available, return -ENOMEM. + */ for (h = 0; h < MAX_HWIFS; ++h) { hwif = &ide_hwifs[h]; - /* Find an empty HWIF */ if (hwif->chipset == ide_unknown) break; } + if (h == MAX_HWIFS) { + printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name); + return -ENOMEM; + } /* Get the CmdBlk and CtrlBlk Base Registers */ base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET; From ceef833bae05e393859f1946a9802fb61f0febdf Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 15 Dec 2005 02:11:55 +0100 Subject: [PATCH 27/91] [PATCH] via82cxxx IDE: Add VT8251 ISA bridge Some motherboards (such as the Asus P5V800-MX) ship a PCI_DEVICE_ID_VIA_82C586_1 IDE controller alongside a VT8251 southbridge. This southbridge is currently unrecognised in the via82cxxx IDE driver, preventing those users from getting DMA access to disks. Signed-off-by: Daniel Drake Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/via82cxxx.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 7161ce0ef5aa..86fb1e0286d3 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -80,6 +80,7 @@ static struct via_isa_bridge { u16 flags; } via_isa_bridges[] = { { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, + { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1e737e269db9..4db67b3b05cc 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1244,6 +1244,7 @@ #define PCI_DEVICE_ID_VIA_8378_0 0x3205 #define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8237 0x3227 +#define PCI_DEVICE_ID_VIA_8251 0x3287 #define PCI_DEVICE_ID_VIA_3296_0 0x0296 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 From 38f9d412be1ed29ee3b41782f22fd85b1c95fbed Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 15 Dec 2005 02:12:53 +0100 Subject: [PATCH 28/91] [PATCH] ide: MPC8xx IDE depends on IDE=y && BLK_DEV_IDE=y The following patch adds a dependancy on IDE=y && BLK_DEV_IDE=y for the MPC8xx IDE driver. The code is not modular at the moment (init called from platform setup code). Signed-off-by: Marcelo Tosatti Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 31e649a9ff71..45579ae12c01 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -940,7 +940,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_MPC8xx_IDE bool "MPC8xx IDE support" - depends on 8xx + depends on 8xx && IDE=y && BLK_DEV_IDE=y help This option provides support for IDE on Motorola MPC8xx Systems. Please see 'Type of MPC8xx IDE interface' for details. From 65e5f2e3b457b6b20a5c4481312189d141a33d24 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 15 Dec 2005 02:16:18 +0100 Subject: [PATCH 29/91] [PATCH] ide: core modifications for AU1200 bart: slightly modified by me Signed-off-by: Jordan Crouse Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 15 ++++++--------- include/asm-mips/mach-au1x00/au1xxx_ide.h | 5 ----- include/linux/ide.h | 6 ++++++ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 1e1531334c25..0523da77425a 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -90,11 +90,6 @@ #include #include -struct drive_list_entry { - const char *id_model; - const char *id_firmware; -}; - static const struct drive_list_entry drive_whitelist [] = { { "Micropolis 2112A" , "ALL" }, @@ -139,7 +134,7 @@ static const struct drive_list_entry drive_blacklist [] = { }; /** - * in_drive_list - look for drive in black/white list + * ide_in_drive_list - look for drive in black/white list * @id: drive identifier * @drive_table: list to inspect * @@ -147,7 +142,7 @@ static const struct drive_list_entry drive_blacklist [] = { * Returns 1 if the drive is found in the table. */ -static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) { for ( ; drive_table->id_model ; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && @@ -157,6 +152,8 @@ static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *d return 0; } +EXPORT_SYMBOL_GPL(ide_in_drive_list); + /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for @@ -663,7 +660,7 @@ int __ide_dma_bad_drive (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - int blacklist = in_drive_list(id, drive_blacklist); + int blacklist = ide_in_drive_list(id, drive_blacklist); if (blacklist) { printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n", drive->name, id->model); @@ -677,7 +674,7 @@ EXPORT_SYMBOL(__ide_dma_bad_drive); int __ide_dma_good_drive (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - return in_drive_list(id, drive_whitelist); + return ide_in_drive_list(id, drive_whitelist); } EXPORT_SYMBOL(__ide_dma_good_drive); diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h index 33d275c3b84c..0c3c127e619e 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -87,11 +87,6 @@ typedef struct } _auide_hwif; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -struct drive_list_entry { - const char * id_model; - const char * id_firmware; -}; - /* HD white list */ static const struct drive_list_entry dma_white_list [] = { /* diff --git a/include/linux/ide.h b/include/linux/ide.h index a39c3c59789d..a6b28dcf8f0d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1371,6 +1371,12 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *); #define GOOD_DMA_DRIVE 1 #ifdef CONFIG_BLK_DEV_IDEDMA +struct drive_list_entry { + const char *id_model; + const char *id_firmware; +}; + +int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); int ide_use_dma(ide_drive_t *); From 8f29e650bffc1e22ed6b2d0b321bc77627f3bb7a Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 15 Dec 2005 02:17:46 +0100 Subject: [PATCH 30/91] [PATCH] ide: AU1200 IDE update Changes here include removing all of CONFIG_PM while it is being repeatedly smacked with a lead pipe, moving the BURSTMODE param to a #define (it should be defined almost always anyway), fixing the rqsize stuff, pulling ide_ioreg_t, and general cleanups and whatnot. Signed-off-by: Jordan Crouse Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 8 - drivers/ide/mips/Makefile | 3 + drivers/ide/mips/au1xxx-ide.c | 1436 +++++++-------------- include/asm-mips/mach-au1x00/au1xxx_ide.h | 17 +- 4 files changed, 512 insertions(+), 952 deletions(-) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 45579ae12c01..1c81174595b3 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -807,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX endchoice -config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - bool "Enable burstable Mode on DbDMA" - default false - depends BLK_DEV_IDE_AU1XXX - help - This option enable the burstable Flag on DbDMA controller - (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY"). - config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ int "Maximum transfer size (KB) per request (up to 128)" default "128" diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile index 578e52a59588..677c7b2bac92 100644 --- a/drivers/ide/mips/Makefile +++ b/drivers/ide/mips/Makefile @@ -1 +1,4 @@ obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o +obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o + +EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index 2b6327c576b9..32431dcf5d8e 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -31,865 +31,638 @@ */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ -#include /* for CONFIG_BLK_DEV_IDEPCI */ #include #include #include #include -#include -#include -#include -#include +#include + #include #include #include #include +#include "ide-timing.h" + #include #include #include -#if CONFIG_PM -#include -#endif - #include #define DRV_NAME "au1200-ide" #define DRV_VERSION "1.0" -#define DRV_AUTHOR "AMD PCS / Pete Popov " -#define DRV_DESC "Au1200 IDE" +#define DRV_AUTHOR "Enrico Walther / Pete Popov " + +/* enable the burstmode in the dbdma */ +#define IDE_AU1XXX_BURSTMODE 1 static _auide_hwif auide_hwif; -static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED; -static int dbdma_init_done = 0; +static int dbdma_init_done; -/* - * local I/O functions - */ -u8 auide_inb(unsigned long port) -{ - return (au_readb(port)); -} - -u16 auide_inw(unsigned long port) -{ - return (au_readw(port)); -} - -u32 auide_inl(unsigned long port) -{ - return (au_readl(port)); -} +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) void auide_insw(unsigned long port, void *addr, u32 count) { -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; - _auide_hwif *ahwif = &auide_hwif; - chan_tab_t *ctp; - au1x_ddma_desc_t *dp; - - if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1, - DDMA_FLAGS_NOIE)) { - printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); - return; - } - ctp = *((chan_tab_t **)ahwif->rx_chan); - dp = ctp->cur_ptr; - while (dp->dscr_cmd0 & DSCR_CMD0_V) - ; - ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); -#else - while (count--) - { - *(u16 *)addr = au_readw(port); - addr +=2 ; - } -#endif -} - -void auide_insl(unsigned long port, void *addr, u32 count) -{ - while (count--) - { - *(u32 *)addr = au_readl(port); - /* NOTE: For IDE interfaces over PCMCIA, - * 32-bit access does not work - */ - addr += 4; - } -} - -void auide_outb(u8 addr, unsigned long port) -{ - return (au_writeb(addr, port)); -} - -void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port) -{ - return (au_writeb(addr, port)); -} - -void auide_outw(u16 addr, unsigned long port) -{ - return (au_writew(addr, port)); -} - -void auide_outl(u32 addr, unsigned long port) -{ - return (au_writel(addr, port)); + if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1, + DDMA_FLAGS_NOIE)) { + printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); + return; + } + ctp = *((chan_tab_t **)ahwif->rx_chan); + dp = ctp->cur_ptr; + while (dp->dscr_cmd0 & DSCR_CMD0_V) + ; + ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); } void auide_outsw(unsigned long port, void *addr, u32 count) { -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) - _auide_hwif *ahwif = &auide_hwif; - chan_tab_t *ctp; - au1x_ddma_desc_t *dp; + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; + + if(!put_source_flags(ahwif->tx_chan, (void*)addr, + count << 1, DDMA_FLAGS_NOIE)) { + printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); + return; + } + ctp = *((chan_tab_t **)ahwif->tx_chan); + dp = ctp->cur_ptr; + while (dp->dscr_cmd0 & DSCR_CMD0_V) + ; + ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); +} - if(!put_source_flags(ahwif->tx_chan, (void*)addr, - count << 1, DDMA_FLAGS_NOIE)) { - printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__); - return; - } - ctp = *((chan_tab_t **)ahwif->tx_chan); - dp = ctp->cur_ptr; - while (dp->dscr_cmd0 & DSCR_CMD0_V) - ; - ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp); -#else - while (count--) - { - au_writew(*(u16 *)addr, port); - addr += 2; - } #endif -} - -void auide_outsl(unsigned long port, void *addr, u32 count) -{ - while (count--) - { - au_writel(*(u32 *)addr, port); - /* NOTE: For IDE interfaces over PCMCIA, - * 32-bit access does not work - */ - addr += 4; - } -} static void auide_tune_drive(ide_drive_t *drive, byte pio) { - int mem_sttime; - int mem_stcfg; - unsigned long flags; - u8 speed; + int mem_sttime; + int mem_stcfg; + u8 speed; - /* get the best pio mode for the drive */ - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); + /* get the best pio mode for the drive */ + pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - printk("%s: setting Au1XXX IDE to PIO mode%d\n", - drive->name, pio); + printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n", + drive->name, pio); - spin_lock_irqsave(&ide_tune_drive_spin_lock, flags); + mem_sttime = 0; + mem_stcfg = au_readl(MEM_STCFG2); - mem_sttime = 0; - mem_stcfg = au_readl(MEM_STCFG2); + /* set pio mode! */ + switch(pio) { + case 0: + mem_sttime = SBC_IDE_TIMING(PIO0); - /* set pio mode! */ - switch(pio) { - case 0: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_PIO0_TWCS - | SBC_IDE_PIO0_TCSH - | SBC_IDE_PIO0_TCSOFF - | SBC_IDE_PIO0_TWP - | SBC_IDE_PIO0_TCSW - | SBC_IDE_PIO0_TPM - | SBC_IDE_PIO0_TA; - /* set configuration for RCS2# */ - mem_stcfg |= TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS; + break; - au_writel(mem_sttime,MEM_STTIME2); - au_writel(mem_stcfg,MEM_STCFG2); - break; + case 1: + mem_sttime = SBC_IDE_TIMING(PIO1); - case 1: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_PIO1_TWCS - | SBC_IDE_PIO1_TCSH - | SBC_IDE_PIO1_TCSOFF - | SBC_IDE_PIO1_TWP - | SBC_IDE_PIO1_TCSW - | SBC_IDE_PIO1_TPM - | SBC_IDE_PIO1_TA; - /* set configuration for RCS2# */ - mem_stcfg |= TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS; - break; + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS; + break; - case 2: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_PIO2_TWCS - | SBC_IDE_PIO2_TCSH - | SBC_IDE_PIO2_TCSOFF - | SBC_IDE_PIO2_TWP - | SBC_IDE_PIO2_TCSW - | SBC_IDE_PIO2_TPM - | SBC_IDE_PIO2_TA; - /* set configuration for RCS2# */ - mem_stcfg &= ~TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS; - break; + case 2: + mem_sttime = SBC_IDE_TIMING(PIO2); - case 3: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_PIO3_TWCS - | SBC_IDE_PIO3_TCSH - | SBC_IDE_PIO3_TCSOFF - | SBC_IDE_PIO3_TWP - | SBC_IDE_PIO3_TCSW - | SBC_IDE_PIO3_TPM - | SBC_IDE_PIO3_TA; - /* set configuration for RCS2# */ - mem_stcfg |= TS_MASK; - mem_stcfg &= ~TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS; + break; - break; + case 3: + mem_sttime = SBC_IDE_TIMING(PIO3); - case 4: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_PIO4_TWCS - | SBC_IDE_PIO4_TCSH - | SBC_IDE_PIO4_TCSOFF - | SBC_IDE_PIO4_TWP - | SBC_IDE_PIO4_TCSW - | SBC_IDE_PIO4_TPM - | SBC_IDE_PIO4_TA; - /* set configuration for RCS2# */ - mem_stcfg &= ~TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS; - break; - } + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS; - au_writel(mem_sttime,MEM_STTIME2); - au_writel(mem_stcfg,MEM_STCFG2); + break; - spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags); + case 4: + mem_sttime = SBC_IDE_TIMING(PIO4); - speed = pio + XFER_PIO_0; - ide_config_drive_speed(drive, speed); + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS; + break; + } + + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); + + speed = pio + XFER_PIO_0; + ide_config_drive_speed(drive, speed); } static int auide_tune_chipset (ide_drive_t *drive, u8 speed) { - u8 mode = 0; - int mem_sttime; - int mem_stcfg; - unsigned long flags; -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - struct hd_driveid *id = drive->id; + int mem_sttime; + int mem_stcfg; + unsigned long mode; - /* - * Now see what the current drive is capable of, - * selecting UDMA only if the mate said it was ok. - */ - if (id && (id->capability & 1) && drive->autodma && - !__ide_dma_bad_drive(drive)) { - if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { - if (id->dma_mword & 4) - mode = XFER_MW_DMA_2; - else if (id->dma_mword & 2) - mode = XFER_MW_DMA_1; - else if (id->dma_mword & 1) - mode = XFER_MW_DMA_0; - } - } +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA + if (ide_use_dma(drive)) + mode = ide_dma_speed(drive, 0); #endif - spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags); + mem_sttime = 0; + mem_stcfg = au_readl(MEM_STCFG2); - mem_sttime = 0; - mem_stcfg = au_readl(MEM_STCFG2); - - switch(speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - auide_tune_drive(drive, (speed - XFER_PIO_0)); - break; + if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) { + auide_tune_drive(drive, speed - XFER_PIO_0); + return 0; + } + + switch(speed) { #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - case XFER_MW_DMA_2: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_MDMA2_TWCS - | SBC_IDE_MDMA2_TCSH - | SBC_IDE_MDMA2_TCSOFF - | SBC_IDE_MDMA2_TWP - | SBC_IDE_MDMA2_TCSW - | SBC_IDE_MDMA2_TPM - | SBC_IDE_MDMA2_TA; - /* set configuration for RCS2# */ - mem_stcfg &= ~TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS; + case XFER_MW_DMA_2: + mem_sttime = SBC_IDE_TIMING(MDMA2); - mode = XFER_MW_DMA_2; - break; - case XFER_MW_DMA_1: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_MDMA1_TWCS - | SBC_IDE_MDMA1_TCSH - | SBC_IDE_MDMA1_TCSOFF - | SBC_IDE_MDMA1_TWP - | SBC_IDE_MDMA1_TCSW - | SBC_IDE_MDMA1_TPM - | SBC_IDE_MDMA1_TA; - /* set configuration for RCS2# */ - mem_stcfg &= ~TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS; - mode = XFER_MW_DMA_1; - break; - case XFER_MW_DMA_0: - /* set timing parameters for RCS2# */ - mem_sttime = SBC_IDE_MDMA0_TWCS - | SBC_IDE_MDMA0_TCSH - | SBC_IDE_MDMA0_TCSOFF - | SBC_IDE_MDMA0_TWP - | SBC_IDE_MDMA0_TCSW - | SBC_IDE_MDMA0_TPM - | SBC_IDE_MDMA0_TA; - /* set configuration for RCS2# */ - mem_stcfg |= TS_MASK; - mem_stcfg &= ~TCSOE_MASK; - mem_stcfg &= ~TOECS_MASK; - mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS; + mode = XFER_MW_DMA_2; + break; + case XFER_MW_DMA_1: + mem_sttime = SBC_IDE_TIMING(MDMA1); - mode = XFER_MW_DMA_0; - break; + /* set configuration for RCS2# */ + mem_stcfg &= ~TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS; + + mode = XFER_MW_DMA_1; + break; + case XFER_MW_DMA_0: + mem_sttime = SBC_IDE_TIMING(MDMA0); + + /* set configuration for RCS2# */ + mem_stcfg |= TS_MASK; + mem_stcfg &= ~TCSOE_MASK; + mem_stcfg &= ~TOECS_MASK; + mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS; + + mode = XFER_MW_DMA_0; + break; #endif - default: - return 1; - } + default: + return 1; + } + + if (ide_config_drive_speed(drive, mode)) + return 1; - /* - * Tell the drive to switch to the new mode; abort on failure. - */ - if (!mode || ide_config_drive_speed(drive, mode)) - { - return 1; /* failure */ - } + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); - - au_writel(mem_sttime,MEM_STTIME2); - au_writel(mem_stcfg,MEM_STCFG2); - - spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags); - - return 0; + return 0; } /* * Multi-Word DMA + DbDMA functions */ -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA -static int in_drive_list(struct hd_driveid *id, - const struct drive_list_entry *drive_table) -{ - for ( ; drive_table->id_model ; drive_table++){ - if ((!strcmp(drive_table->id_model, id->model)) && - ((strstr(drive_table->id_firmware, id->fw_rev)) || - (!strcmp(drive_table->id_firmware, "ALL"))) - ) - return 1; - } - return 0; -} +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA static int auide_build_sglist(ide_drive_t *drive, struct request *rq) { - ide_hwif_t *hwif = drive->hwif; - _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; - struct scatterlist *sg = hwif->sg_table; + ide_hwif_t *hwif = drive->hwif; + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + struct scatterlist *sg = hwif->sg_table; - ide_map_sg(drive, rq); + ide_map_sg(drive, rq); - if (rq_data_dir(rq) == READ) - hwif->sg_dma_direction = DMA_FROM_DEVICE; - else - hwif->sg_dma_direction = DMA_TO_DEVICE; + if (rq_data_dir(rq) == READ) + hwif->sg_dma_direction = DMA_FROM_DEVICE; + else + hwif->sg_dma_direction = DMA_TO_DEVICE; - return dma_map_sg(ahwif->dev, sg, hwif->sg_nents, - hwif->sg_dma_direction); + return dma_map_sg(ahwif->dev, sg, hwif->sg_nents, + hwif->sg_dma_direction); } static int auide_build_dmatable(ide_drive_t *drive) { - int i, iswrite, count = 0; - ide_hwif_t *hwif = HWIF(drive); + int i, iswrite, count = 0; + ide_hwif_t *hwif = HWIF(drive); - struct request *rq = HWGROUP(drive)->rq; + struct request *rq = HWGROUP(drive)->rq; - _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; - struct scatterlist *sg; + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + struct scatterlist *sg; - iswrite = (rq_data_dir(rq) == WRITE); - /* Save for interrupt context */ - ahwif->drive = drive; + iswrite = (rq_data_dir(rq) == WRITE); + /* Save for interrupt context */ + ahwif->drive = drive; - /* Build sglist */ - hwif->sg_nents = i = auide_build_sglist(drive, rq); + /* Build sglist */ + hwif->sg_nents = i = auide_build_sglist(drive, rq); - if (!i) - return 0; + if (!i) + return 0; - /* fill the descriptors */ - sg = hwif->sg_table; - while (i && sg_dma_len(sg)) { - u32 cur_addr; - u32 cur_len; + /* fill the descriptors */ + sg = hwif->sg_table; + while (i && sg_dma_len(sg)) { + u32 cur_addr; + u32 cur_len; - cur_addr = sg_dma_address(sg); - cur_len = sg_dma_len(sg); + cur_addr = sg_dma_address(sg); + cur_len = sg_dma_len(sg); - while (cur_len) { - u32 flags = DDMA_FLAGS_NOIE; - unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; + while (cur_len) { + u32 flags = DDMA_FLAGS_NOIE; + unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00; - if (++count >= PRD_ENTRIES) { - printk(KERN_WARNING "%s: DMA table too small\n", - drive->name); - goto use_pio_instead; - } + if (++count >= PRD_ENTRIES) { + printk(KERN_WARNING "%s: DMA table too small\n", + drive->name); + goto use_pio_instead; + } - /* Lets enable intr for the last descriptor only */ - if (1==i) - flags = DDMA_FLAGS_IE; - else - flags = DDMA_FLAGS_NOIE; + /* Lets enable intr for the last descriptor only */ + if (1==i) + flags = DDMA_FLAGS_IE; + else + flags = DDMA_FLAGS_NOIE; - if (iswrite) { - if(!put_source_flags(ahwif->tx_chan, - (void*)(page_address(sg->page) - + sg->offset), - tc, flags)) { - printk(KERN_ERR "%s failed %d\n", - __FUNCTION__, __LINE__); + if (iswrite) { + if(!put_source_flags(ahwif->tx_chan, + (void*)(page_address(sg->page) + + sg->offset), + tc, flags)) { + printk(KERN_ERR "%s failed %d\n", + __FUNCTION__, __LINE__); } - } else + } else { - if(!put_dest_flags(ahwif->rx_chan, - (void*)(page_address(sg->page) - + sg->offset), - tc, flags)) { - printk(KERN_ERR "%s failed %d\n", - __FUNCTION__, __LINE__); + if(!put_dest_flags(ahwif->rx_chan, + (void*)(page_address(sg->page) + + sg->offset), + tc, flags)) { + printk(KERN_ERR "%s failed %d\n", + __FUNCTION__, __LINE__); } - } + } - cur_addr += tc; - cur_len -= tc; - } - sg++; - i--; - } + cur_addr += tc; + cur_len -= tc; + } + sg++; + i--; + } - if (count) - return 1; + if (count) + return 1; -use_pio_instead: - dma_unmap_sg(ahwif->dev, - hwif->sg_table, - hwif->sg_nents, - hwif->sg_dma_direction); + use_pio_instead: + dma_unmap_sg(ahwif->dev, + hwif->sg_table, + hwif->sg_nents, + hwif->sg_dma_direction); - return 0; /* revert to PIO for this request */ + return 0; /* revert to PIO for this request */ } static int auide_dma_end(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + ide_hwif_t *hwif = HWIF(drive); + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; - if (hwif->sg_nents) { - dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents, - hwif->sg_dma_direction); - hwif->sg_nents = 0; - } + if (hwif->sg_nents) { + dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents, + hwif->sg_dma_direction); + hwif->sg_nents = 0; + } - return 0; + return 0; } static void auide_dma_start(ide_drive_t *drive ) { -// printk("%s\n", __FUNCTION__); } -ide_startstop_t auide_dma_intr(ide_drive_t *drive) -{ - //printk("%s\n", __FUNCTION__); - - u8 stat = 0, dma_stat = 0; - - dma_stat = HWIF(drive)->ide_dma_end(drive); - stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */ - if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { - if (!dma_stat) { - struct request *rq = HWGROUP(drive)->rq; - - ide_end_request(drive, 1, rq->nr_sectors); - return ide_stopped; - } - printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", - drive->name, dma_stat); - } - return ide_error(drive, "dma_intr", stat); -} static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) { - //printk("%s\n", __FUNCTION__); - - /* issue cmd to drive */ - ide_execute_command(drive, command, &auide_dma_intr, - (2*WAIT_CMD), NULL); + /* issue cmd to drive */ + ide_execute_command(drive, command, &ide_dma_intr, + (2*WAIT_CMD), NULL); } static int auide_dma_setup(ide_drive_t *drive) -{ -// printk("%s\n", __FUNCTION__); +{ + struct request *rq = HWGROUP(drive)->rq; - if (drive->media != ide_disk) - return 1; + if (!auide_build_dmatable(drive)) { + ide_map_sg(drive, rq); + return 1; + } - if (!auide_build_dmatable(drive)) - /* try PIO instead of DMA */ - return 1; - - drive->waiting_for_dma = 1; - - return 0; + drive->waiting_for_dma = 1; + return 0; } static int auide_dma_check(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); + u8 speed; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - if( !dbdma_init_done ){ - auide_hwif.white_list = in_drive_list(drive->id, - dma_white_list); - auide_hwif.black_list = in_drive_list(drive->id, - dma_black_list); - auide_hwif.drive = drive; - auide_ddma_init(&auide_hwif); - dbdma_init_done = 1; - } + + if( dbdma_init_done == 0 ){ + auide_hwif.white_list = ide_in_drive_list(drive->id, + dma_white_list); + auide_hwif.black_list = ide_in_drive_list(drive->id, + dma_black_list); + auide_hwif.drive = drive; + auide_ddma_init(&auide_hwif); + dbdma_init_done = 1; + } #endif - /* Is the drive in our DMA black list? */ - if ( auide_hwif.black_list ) { - drive->using_dma = 0; - printk("%s found in dma_blacklist[]! Disabling DMA.\n", - drive->id->model); - } - else - drive->using_dma = 1; + /* Is the drive in our DMA black list? */ - return HWIF(drive)->ide_dma_host_on(drive); + if ( auide_hwif.black_list ) { + drive->using_dma = 0; + + /* Borrowed the warning message from ide-dma.c */ + + printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n", + drive->name, drive->id->model); + } + else + drive->using_dma = 1; + + speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA); + + if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) + return HWIF(drive)->ide_dma_on(drive); + + return HWIF(drive)->ide_dma_off_quietly(drive); } static int auide_dma_test_irq(ide_drive_t *drive) -{ -// printk("%s\n", __FUNCTION__); - - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: ide_dma_test_irq \ +{ + if (drive->waiting_for_dma == 0) + printk(KERN_WARNING "%s: ide_dma_test_irq \ called while not waiting\n", drive->name); - /* If dbdma didn't execute the STOP command yet, the - * active bit is still set + /* If dbdma didn't execute the STOP command yet, the + * active bit is still set */ - drive->waiting_for_dma++; - if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { - printk(KERN_WARNING "%s: timeout waiting for ddma to \ + drive->waiting_for_dma++; + if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { + printk(KERN_WARNING "%s: timeout waiting for ddma to \ complete\n", drive->name); - return 1; - } - udelay(10); - return 0; + return 1; + } + udelay(10); + return 0; } static int auide_dma_host_on(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); - return 0; + return 0; } static int auide_dma_on(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); - drive->using_dma = 1; - return auide_dma_host_on(drive); + drive->using_dma = 1; + return auide_dma_host_on(drive); } static int auide_dma_host_off(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); - return 0; + return 0; } static int auide_dma_off_quietly(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); - drive->using_dma = 0; - return auide_dma_host_off(drive); + drive->using_dma = 0; + return auide_dma_host_off(drive); } static int auide_dma_lostirq(ide_drive_t *drive) { -// printk("%s\n", __FUNCTION__); - - printk(KERN_ERR "%s: IRQ lost\n", drive->name); - return 0; + printk(KERN_ERR "%s: IRQ lost\n", drive->name); + return 0; } static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs) { -// printk("%s\n", __FUNCTION__); - - _auide_hwif *ahwif = (_auide_hwif*)param; - ahwif->drive->waiting_for_dma = 0; - return; + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; } static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs) { -// printk("%s\n", __FUNCTION__); - - _auide_hwif *ahwif = (_auide_hwif*)param; - ahwif->drive->waiting_for_dma = 0; - return; + _auide_hwif *ahwif = (_auide_hwif*)param; + ahwif->drive->waiting_for_dma = 0; } +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ + +static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags) +{ + dev->dev_id = dev_id; + dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; + dev->dev_intlevel = 0; + dev->dev_intpolarity = 0; + dev->dev_tsize = tsize; + dev->dev_devwidth = devwidth; + dev->dev_flags = flags; +} + +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) + static int auide_dma_timeout(ide_drive_t *drive) { // printk("%s\n", __FUNCTION__); - printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); + printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); - if (HWIF(drive)->ide_dma_test_irq(drive)) - return 0; + if (HWIF(drive)->ide_dma_test_irq(drive)) + return 0; - return HWIF(drive)->ide_dma_end(drive); + return HWIF(drive)->ide_dma_end(drive); } -#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ + +static int auide_ddma_init(_auide_hwif *auide) { + + dbdev_tab_t source_dev_tab, target_dev_tab; + u32 dev_id, tsize, devwidth, flags; + ide_hwif_t *hwif = auide->hwif; + dev_id = AU1XXX_ATA_DDMA_REQ; + + if (auide->white_list || auide->black_list) { + tsize = 8; + devwidth = 32; + } + else { + tsize = 1; + devwidth = 16; + + printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model); + printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'"); + } + +#ifdef IDE_AU1XXX_BURSTMODE + flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE; +#else + flags = DEV_FLAGS_SYNC; +#endif + + /* setup dev_tab for tx channel */ + auide_init_dbdma_dev( &source_dev_tab, + dev_id, + tsize, devwidth, DEV_FLAGS_OUT | flags); + auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); + + auide_init_dbdma_dev( &source_dev_tab, + dev_id, + tsize, devwidth, DEV_FLAGS_IN | flags); + auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); + + /* We also need to add a target device for the DMA */ + auide_init_dbdma_dev( &target_dev_tab, + (u32)DSCR_CMD0_ALWAYS, + tsize, devwidth, DEV_FLAGS_ANYUSE); + auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); + + /* Get a channel for TX */ + auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id, + auide->tx_dev_id, + auide_ddma_tx_callback, + (void*)auide); + + /* Get a channel for RX */ + auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, + auide->target_dev_id, + auide_ddma_rx_callback, + (void*)auide); + + auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, + NUM_DESCRIPTORS); + auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, + NUM_DESCRIPTORS); + + hwif->dmatable_cpu = dma_alloc_coherent(auide->dev, + PRD_ENTRIES * PRD_BYTES, /* 1 Page */ + &hwif->dmatable_dma, GFP_KERNEL); + + au1xxx_dbdma_start( auide->tx_chan ); + au1xxx_dbdma_start( auide->rx_chan ); + + return 0; +} +#else + static int auide_ddma_init( _auide_hwif *auide ) { -// printk("%s\n", __FUNCTION__); + dbdev_tab_t source_dev_tab; + int flags; - dbdev_tab_t source_dev_tab; -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) - dbdev_tab_t target_dev_tab; - ide_hwif_t *hwif = auide->hwif; - char warning_output [2][80]; - int i; -#endif - - /* Add our custom device to DDMA device table */ - /* Create our new device entries in the table */ -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) - source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ; - - if( auide->white_list || auide->black_list ){ - source_dev_tab.dev_tsize = 8; - source_dev_tab.dev_devwidth = 32; - source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; - source_dev_tab.dev_intlevel = 0; - source_dev_tab.dev_intpolarity = 0; - - /* init device table for target - static bus controller - */ - target_dev_tab.dev_id = DSCR_CMD0_ALWAYS; - target_dev_tab.dev_tsize = 8; - target_dev_tab.dev_devwidth = 32; - target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; - target_dev_tab.dev_intlevel = 0; - target_dev_tab.dev_intpolarity = 0; - target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE; - } - else{ - source_dev_tab.dev_tsize = 1; - source_dev_tab.dev_devwidth = 16; - source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; - source_dev_tab.dev_intlevel = 0; - source_dev_tab.dev_intpolarity = 0; - - /* init device table for target - static bus controller - */ - target_dev_tab.dev_id = DSCR_CMD0_ALWAYS; - target_dev_tab.dev_tsize = 1; - target_dev_tab.dev_devwidth = 16; - target_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; - target_dev_tab.dev_intlevel = 0; - target_dev_tab.dev_intpolarity = 0; - target_dev_tab.dev_flags = DEV_FLAGS_ANYUSE; - - sprintf(&warning_output[0][0], - "%s is not on ide driver white list.", - auide_hwif.drive->id->model); - for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){ - sprintf(&warning_output[0][i]," "); - } - - sprintf(&warning_output[1][0], - "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.", - auide_hwif.drive->id->model); - for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){ - sprintf(&warning_output[1][i]," "); - } - - printk("\n****************************************"); - printk("****************************************\n"); - printk("* %s *\n",&warning_output[0][0]); - printk("* Switch to safe MWDMA Mode! "); - printk(" *\n"); - printk("* %s *\n",&warning_output[1][0]); - printk("****************************************"); - printk("****************************************\n\n"); - } +#ifdef IDE_AU1XXX_BURSTMODE + flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE; #else - source_dev_tab.dev_id = DSCR_CMD0_ALWAYS; - source_dev_tab.dev_tsize = 8; - source_dev_tab.dev_devwidth = 32; - source_dev_tab.dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; - source_dev_tab.dev_intlevel = 0; - source_dev_tab.dev_intpolarity = 0; + flags = DEV_FLAGS_SYNC; #endif -#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - /* set flags for tx channel */ - source_dev_tab.dev_flags = DEV_FLAGS_OUT - | DEV_FLAGS_SYNC - | DEV_FLAGS_BURSTABLE; - auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); - /* set flags for rx channel */ - source_dev_tab.dev_flags = DEV_FLAGS_IN - | DEV_FLAGS_SYNC - | DEV_FLAGS_BURSTABLE; - auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); -#else - /* set flags for tx channel */ - source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC; - auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); - /* set flags for rx channel */ - source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC; - auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); -#endif + /* setup dev_tab for tx channel */ + auide_init_dbdma_dev( &source_dev_tab, + (u32)DSCR_CMD0_ALWAYS, + 8, 32, DEV_FLAGS_OUT | flags); + auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) - - auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); - - /* Get a channel for TX */ - auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id, - auide->tx_dev_id, - auide_ddma_tx_callback, - (void*)auide); - /* Get a channel for RX */ - auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, - auide->target_dev_id, - auide_ddma_rx_callback, - (void*)auide); -#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */ - /* - * Note: if call back is not enabled, update ctp->cur_ptr manually - */ - auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, - auide->tx_dev_id, - NULL, - (void*)auide); - auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, - DSCR_CMD0_ALWAYS, - NULL, - (void*)auide); -#endif - auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, - NUM_DESCRIPTORS); - auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, - NUM_DESCRIPTORS); - -#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) - hwif->dmatable_cpu = dma_alloc_coherent(auide->dev, - PRD_ENTRIES * PRD_BYTES, /* 1 Page */ - &hwif->dmatable_dma, GFP_KERNEL); - - auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES, - GFP_KERNEL|GFP_DMA); - if (auide->sg_table == NULL) { - return -ENOMEM; - } -#endif - au1xxx_dbdma_start( auide->tx_chan ); - au1xxx_dbdma_start( auide->rx_chan ); - return 0; + auide_init_dbdma_dev( &source_dev_tab, + (u32)DSCR_CMD0_ALWAYS, + 8, 32, DEV_FLAGS_IN | flags); + auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); + + /* Get a channel for TX */ + auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, + auide->tx_dev_id, + NULL, + (void*)auide); + + /* Get a channel for RX */ + auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, + DSCR_CMD0_ALWAYS, + NULL, + (void*)auide); + + auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, + NUM_DESCRIPTORS); + auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, + NUM_DESCRIPTORS); + + au1xxx_dbdma_start( auide->tx_chan ); + au1xxx_dbdma_start( auide->rx_chan ); + + return 0; } +#endif static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif) { - int i; -#define ide_ioreg_t unsigned long - ide_ioreg_t *ata_regs = hw->io_ports; + int i; + unsigned long *ata_regs = hw->io_ports; - /* fixme */ - for (i = 0; i < IDE_CONTROL_OFFSET; i++) { - *ata_regs++ = (ide_ioreg_t) ahwif->regbase - + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET); - } + /* FIXME? */ + for (i = 0; i < IDE_CONTROL_OFFSET; i++) { + *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET); + } - /* set the Alternative Status register */ - *ata_regs = (ide_ioreg_t) ahwif->regbase - + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET); + /* set the Alternative Status register */ + *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET); } static int au_ide_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - _auide_hwif *ahwif = &auide_hwif; - ide_hwif_t *hwif; + _auide_hwif *ahwif = &auide_hwif; + ide_hwif_t *hwif; struct resource *res; int ret = 0; #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) - char *mode = "MWDMA2"; + char *mode = "MWDMA2"; #elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) - char *mode = "PIO+DDMA(offload)"; + char *mode = "PIO+DDMA(offload)"; #endif - memset(&auide_hwif, 0, sizeof(_auide_hwif)); - auide_hwif.dev = 0; + memset(&auide_hwif, 0, sizeof(_auide_hwif)); + auide_hwif.dev = 0; ahwif->dev = dev; ahwif->irq = platform_get_irq(pdev, 0); @@ -902,11 +675,11 @@ static int au_ide_probe(struct device *dev) goto out; } - if (!request_mem_region (res->start, res->end-res->start, pdev->name)) { + if (!request_mem_region (res->start, res->end-res->start, pdev->name)) { pr_debug("%s: request_mem_region failed\n", DRV_NAME); - ret = -EBUSY; + ret = -EBUSY; goto out; - } + } ahwif->regbase = (u32)ioremap(res->start, res->end-res->start); if (ahwif->regbase == 0) { @@ -914,130 +687,92 @@ static int au_ide_probe(struct device *dev) goto out; } - hwif = &ide_hwifs[pdev->id]; - hw_regs_t *hw = &hwif->hw; - hwif->irq = hw->irq = ahwif->irq; - hwif->chipset = ide_au1xxx; + /* FIXME: This might possibly break PCMCIA IDE devices */ - auide_setup_ports(hw, ahwif); + hwif = &ide_hwifs[pdev->id]; + hw_regs_t *hw = &hwif->hw; + hwif->irq = hw->irq = ahwif->irq; + hwif->chipset = ide_au1xxx; + + auide_setup_ports(hw, ahwif); memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ; - hwif->rqsize = ((hwif->rqsize > AU1XXX_ATA_RQSIZE) - || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize; -#else /* if kernel config is not set */ - hwif->rqsize = AU1XXX_ATA_RQSIZE; -#endif - - hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ + hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */ - hwif->swdma_mask = 0x07; + hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */ + hwif->swdma_mask = 0x00; #else - hwif->mwdma_mask = 0x0; - hwif->swdma_mask = 0x0; + hwif->mwdma_mask = 0x0; + hwif->swdma_mask = 0x0; #endif - //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; - hwif->noprobe = 0; - hwif->drives[0].unmask = 1; - hwif->drives[1].unmask = 1; - /* hold should be on in all cases */ - hwif->hold = 1; - hwif->mmio = 2; + hwif->noprobe = 0; + hwif->drives[0].unmask = 1; + hwif->drives[1].unmask = 1; - /* set up local I/O function entry points */ - hwif->INB = auide_inb; - hwif->INW = auide_inw; - hwif->INL = auide_inl; - hwif->INSW = auide_insw; - hwif->INSL = auide_insl; - hwif->OUTB = auide_outb; - hwif->OUTBSYNC = auide_outbsync; - hwif->OUTW = auide_outw; - hwif->OUTL = auide_outl; - hwif->OUTSW = auide_outsw; - hwif->OUTSL = auide_outsl; + /* hold should be on in all cases */ + hwif->hold = 1; + hwif->mmio = 2; - hwif->tuneproc = &auide_tune_drive; - hwif->speedproc = &auide_tune_chipset; + /* If the user has selected DDMA assisted copies, + then set up a few local I/O function entry points + */ + +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA + hwif->INSW = auide_insw; + hwif->OUTSW = auide_outsw; +#endif + + hwif->tuneproc = &auide_tune_drive; + hwif->speedproc = &auide_tune_chipset; #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - hwif->ide_dma_off_quietly = &auide_dma_off_quietly; - hwif->ide_dma_timeout = &auide_dma_timeout; + hwif->ide_dma_off_quietly = &auide_dma_off_quietly; + hwif->ide_dma_timeout = &auide_dma_timeout; - hwif->ide_dma_check = &auide_dma_check; - hwif->dma_exec_cmd = &auide_dma_exec_cmd; - hwif->dma_start = &auide_dma_start; - hwif->ide_dma_end = &auide_dma_end; - hwif->dma_setup = &auide_dma_setup; - hwif->ide_dma_test_irq = &auide_dma_test_irq; - hwif->ide_dma_host_off = &auide_dma_host_off; - hwif->ide_dma_host_on = &auide_dma_host_on; - hwif->ide_dma_lostirq = &auide_dma_lostirq; - hwif->ide_dma_on = &auide_dma_on; + hwif->ide_dma_check = &auide_dma_check; + hwif->dma_exec_cmd = &auide_dma_exec_cmd; + hwif->dma_start = &auide_dma_start; + hwif->ide_dma_end = &auide_dma_end; + hwif->dma_setup = &auide_dma_setup; + hwif->ide_dma_test_irq = &auide_dma_test_irq; + hwif->ide_dma_host_off = &auide_dma_host_off; + hwif->ide_dma_host_on = &auide_dma_host_on; + hwif->ide_dma_lostirq = &auide_dma_lostirq; + hwif->ide_dma_on = &auide_dma_on; + + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + hwif->atapi_dma = 1; - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - hwif->atapi_dma = 1; - hwif->drives[0].using_dma = 1; - hwif->drives[1].using_dma = 1; #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ - hwif->autodma = 0; - hwif->channel = 0; - hwif->hold = 1; - hwif->select_data = 0; /* no chipset-specific code */ - hwif->config_data = 0; /* no chipset-specific code */ + hwif->autodma = 0; + hwif->channel = 0; + hwif->hold = 1; + hwif->select_data = 0; /* no chipset-specific code */ + hwif->config_data = 0; /* no chipset-specific code */ - hwif->drives[0].autodma = 0; - hwif->drives[0].drive_data = 0; /* no drive data */ - hwif->drives[0].using_dma = 0; - hwif->drives[0].waiting_for_dma = 0; - hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ - /* secondary hdd not supported */ - hwif->drives[1].autodma = 0; - - hwif->drives[1].drive_data = 0; - hwif->drives[1].using_dma = 0; - hwif->drives[1].waiting_for_dma = 0; - hwif->drives[1].autotune = 2; /* 1=autotune, 2=noautotune, 0=default */ + hwif->drives[0].autodma = 0; + hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ #endif - hwif->drives[0].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ - hwif->drives[1].io_32bit = 0; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ + hwif->drives[0].no_io_32bit = 1; - /*Register Driver with PM Framework*/ -#ifdef CONFIG_PM - auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED; - auide_hwif.pm.stopped = 0; + auide_hwif.hwif = hwif; + hwif->hwif_data = &auide_hwif; - auide_hwif.pm.dev = new_au1xxx_power_device( "ide", - &au1200ide_pm_callback, - NULL); - if ( auide_hwif.pm.dev == NULL ) - printk(KERN_INFO "Unable to create a power management \ - device entry for the au1200-IDE.\n"); - else - printk(KERN_INFO "Power management device entry for the \ - au1200-IDE loaded.\n"); -#endif - - auide_hwif.hwif = hwif; - hwif->hwif_data = &auide_hwif; - -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - auide_ddma_init(&auide_hwif); - dbdma_init_done = 1; +#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA + auide_ddma_init(&auide_hwif); + dbdma_init_done = 1; #endif probe_hwif_init(hwif); dev_set_drvdata(dev, hwif); - printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); + printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); -out: - return ret; + out: + return ret; } static int au_ide_remove(struct device *dev) @@ -1045,7 +780,7 @@ static int au_ide_remove(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct resource *res; ide_hwif_t *hwif = dev_get_drvdata(dev); - _auide_hwif *ahwif = &auide_hwif; + _auide_hwif *ahwif = &auide_hwif; ide_unregister(hwif - ide_hwifs); @@ -1069,180 +804,11 @@ static int __init au_ide_init(void) return driver_register(&au1200_ide_driver); } -static void __init au_ide_exit(void) +static void __exit au_ide_exit(void) { driver_unregister(&au1200_ide_driver); } -#ifdef CONFIG_PM -int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\ - au1xxx_request_t request, void *data) { - - unsigned int d, err = 0; - unsigned long flags; - - spin_lock_irqsave(auide_hwif.pm.lock, flags); - - switch (request){ - case AU1XXX_PM_SLEEP: - err = au1xxxide_pm_sleep(dev); - break; - case AU1XXX_PM_WAKEUP: - d = *((unsigned int*)data); - if ( d > 0 && d <= 99) { - err = au1xxxide_pm_standby(dev); - } - else { - err = au1xxxide_pm_resume(dev); - } - break; - case AU1XXX_PM_GETSTATUS: - err = au1xxxide_pm_getstatus(dev); - break; - case AU1XXX_PM_ACCESS: - err = au1xxxide_pm_access(dev); - break; - case AU1XXX_PM_IDLE: - err = au1xxxide_pm_idle(dev); - break; - case AU1XXX_PM_CLEANUP: - err = au1xxxide_pm_cleanup(dev); - break; - default: - err = -1; - break; - } - - spin_unlock_irqrestore(auide_hwif.pm.lock, flags); - - return err; -} - -static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) { - return 0; -} - -static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) { - - int retval; - ide_hwif_t *hwif = auide_hwif.hwif; - struct request rq; - struct request_pm_state rqpm; - ide_task_t args; - - if(auide_hwif.pm.stopped) - return -1; - - /* - * wait until hard disc is ready - */ - if ( wait_for_ready(&hwif->drives[0], 35000) ) { - printk("Wait for drive sleep timeout!\n"); - retval = -1; - } - - /* - * sequenz to tell the high level ide driver that pm is resuming - */ - memset(&rq, 0, sizeof(rq)); - memset(&rqpm, 0, sizeof(rqpm)); - memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_SUSPEND; - rq.special = &args; - rq.pm = &rqpm; - rqpm.pm_step = ide_pm_state_start_suspend; - rqpm.pm_state = PMSG_SUSPEND; - - retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait); - - if (wait_for_ready (&hwif->drives[0], 35000)) { - printk("Wait for drive sleep timeout!\n"); - retval = -1; - } - - /* - * stop dbdma channels - */ - au1xxx_dbdma_reset(auide_hwif.tx_chan); - au1xxx_dbdma_reset(auide_hwif.rx_chan); - - auide_hwif.pm.stopped = 1; - - return retval; -} - -static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) { - - int retval; - ide_hwif_t *hwif = auide_hwif.hwif; - struct request rq; - struct request_pm_state rqpm; - ide_task_t args; - - if(!auide_hwif.pm.stopped) - return -1; - - /* - * start dbdma channels - */ - au1xxx_dbdma_start(auide_hwif.tx_chan); - au1xxx_dbdma_start(auide_hwif.rx_chan); - - /* - * wait until hard disc is ready - */ - if (wait_for_ready ( &hwif->drives[0], 35000)) { - printk("Wait for drive wake up timeout!\n"); - retval = -1; - } - - /* - * sequenz to tell the high level ide driver that pm is resuming - */ - memset(&rq, 0, sizeof(rq)); - memset(&rqpm, 0, sizeof(rqpm)); - memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_RESUME; - rq.special = &args; - rq.pm = &rqpm; - rqpm.pm_step = ide_pm_state_start_resume; - rqpm.pm_state = PMSG_ON; - - retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait); - - /* - * wait for hard disc - */ - if ( wait_for_ready(&hwif->drives[0], 35000) ) { - printk("Wait for drive wake up timeout!\n"); - retval = -1; - } - - auide_hwif.pm.stopped = 0; - - return retval; -} - -static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) { - return dev->cur_state; -} - -static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) { - if (dev->cur_state != AWAKE_STATE) - return 0; - else - return -1; -} - -static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) { - return 0; -} - -static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) { - return 0; -} -#endif /* CONFIG_PM */ - MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("AU1200 IDE driver"); diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h index 0c3c127e619e..e867b4ef96d1 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -74,9 +74,6 @@ typedef struct u8 white_list, black_list; struct dbdma_cmd *dma_table_cpu; dma_addr_t dma_table_dma; - struct scatterlist *sg_table; - int sg_nents; - int sg_dma_direction; #endif struct device *dev; int irq; @@ -162,13 +159,9 @@ int __init auide_probe(void); * Multi-Word DMA + DbDMA functions */ #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - - static int in_drive_list(struct hd_driveid *id, - const struct drive_list_entry *drive_table); static int auide_build_sglist(ide_drive_t *drive, struct request *rq); static int auide_build_dmatable(ide_drive_t *drive); static int auide_dma_end(ide_drive_t *drive); - static void auide_dma_start(ide_drive_t *drive ); ide_startstop_t auide_dma_intr (ide_drive_t *drive); static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command); static int auide_dma_setup(ide_drive_t *drive); @@ -183,8 +176,6 @@ int __init auide_probe(void); static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs); static int auide_dma_off_quietly(ide_drive_t *drive); - static int auide_dma_timeout(ide_drive_t *drive); - #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ /******************************************************************************* @@ -294,3 +285,11 @@ int __init auide_probe(void); #define SBC_IDE_MDMA2_TPM (0x00<<6) #define SBC_IDE_MDMA2_TA (0x12<<0) +#define SBC_IDE_TIMING(mode) \ + SBC_IDE_##mode##_TWCS | \ + SBC_IDE_##mode##_TCSH | \ + SBC_IDE_##mode##_TCSOFF | \ + SBC_IDE_##mode##_TWP | \ + SBC_IDE_##mode##_TCSW | \ + SBC_IDE_##mode##_TPM | \ + SBC_IDE_##mode##_TA From d36fef6f5aa4a6a1f44490455393a5b22137a6cd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:19:20 +0100 Subject: [PATCH 31/91] [PATCH] ide-disk: flush cache after calling del_gendisk() Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index f4e3d3527b0e..449522f0540c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1034,12 +1034,12 @@ static int ide_disk_remove(struct device *dev) struct ide_disk_obj *idkp = drive->driver_data; struct gendisk *g = idkp->disk; - ide_cacheflush_p(drive); - ide_unregister_subdriver(drive, idkp->driver); del_gendisk(g); + ide_cacheflush_p(drive); + ide_disk_put(idkp); return 0; From 517bd1d5eac739a7f398058a9524386667fff032 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:19:57 +0100 Subject: [PATCH 32/91] [PATCH] ide: cleanup ide.h Remove: * stale comment * unused HOST() macro * unused ata_{error,control}_t types * unused atapi_select_t type * ide_init_subdrivers() prototype Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 122 -------------------------------------------- 1 file changed, 122 deletions(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index a6b28dcf8f0d..613534b77054 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -23,17 +23,6 @@ #include #include -/* - * This is the multiple IDE interface driver, as evolved from hd.c. - * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15). - * There can be up to two drives per interface, as per the ATA-2 spec. - * - * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64 - * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64 - * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64 - * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64 - */ - /****************************************************************************** * IDE driver configuration options (play with these as desired): * @@ -193,11 +182,6 @@ typedef unsigned char byte; /* used everywhere */ #define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ #define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ -#define HOST(hwif,chipset) \ -{ \ - return ((hwif)->chipset == chipset) ? 1 : 0; \ -} - /* * Check for an interrupt and acknowledge the interrupt status */ @@ -390,45 +374,6 @@ typedef union { } b; } ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t; -/* - * ATA-IDE Error Register - * - * mark : Bad address mark - * tzero : Couldn't find track 0 - * abrt : Aborted Command - * mcr : Media Change Request - * id : ID field not found - * mce : Media Change Event - * ecc : Uncorrectable ECC error - * bdd : dual meaing - */ -typedef union { - unsigned all :8; - struct { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned mark :1; - unsigned tzero :1; - unsigned abrt :1; - unsigned mcr :1; - unsigned id :1; - unsigned mce :1; - unsigned ecc :1; - unsigned bdd :1; -#elif defined(__BIG_ENDIAN_BITFIELD) - unsigned bdd :1; - unsigned ecc :1; - unsigned mce :1; - unsigned id :1; - unsigned mcr :1; - unsigned abrt :1; - unsigned tzero :1; - unsigned mark :1; -#else -#error "Please fix " -#endif - } b; -} ata_error_t; - /* * ATA-IDE Select Register, aka Device-Head * @@ -503,39 +448,6 @@ typedef union { } b; } ata_status_t, atapi_status_t; -/* - * ATA-IDE Control Register - * - * bit0 : Should be set to zero - * nIEN : device INTRQ to host - * SRST : host soft reset bit - * bit3 : ATA-2 thingy, Should be set to 1 - * reserved456 : Reserved - * HOB : 48-bit address ordering, High Ordered Bit - */ -typedef union { - unsigned all : 8; - struct { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned bit0 : 1; - unsigned nIEN : 1; - unsigned SRST : 1; - unsigned bit3 : 1; - unsigned reserved456 : 3; - unsigned HOB : 1; -#elif defined(__BIG_ENDIAN_BITFIELD) - unsigned HOB : 1; - unsigned reserved456 : 3; - unsigned bit3 : 1; - unsigned SRST : 1; - unsigned nIEN : 1; - unsigned bit0 : 1; -#else -#error "Please fix " -#endif - } b; -} ata_control_t; - /* * ATAPI Feature Register * @@ -617,39 +529,6 @@ typedef union { } b; } atapi_error_t; -/* - * ATAPI floppy Drive Select Register - * - * sam_lun : Logical unit number - * reserved3 : Reserved - * drv : The responding drive will be drive 0 (0) or drive 1 (1) - * one5 : Should be set to 1 - * reserved6 : Reserved - * one7 : Should be set to 1 - */ -typedef union { - unsigned all :8; - struct { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned sam_lun :3; - unsigned reserved3 :1; - unsigned drv :1; - unsigned one5 :1; - unsigned reserved6 :1; - unsigned one7 :1; -#elif defined(__BIG_ENDIAN_BITFIELD) - unsigned one7 :1; - unsigned reserved6 :1; - unsigned one5 :1; - unsigned drv :1; - unsigned reserved3 :1; - unsigned sam_lun :3; -#else -#error "Please fix " -#endif - } b; -} atapi_select_t; - /* * Status returned from various ide_ functions */ @@ -1298,7 +1177,6 @@ extern int ide_spin_wait_hwgroup(ide_drive_t *); extern void ide_timer_expiry(unsigned long); extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs); extern void do_ide_request(request_queue_t *); -extern void ide_init_subdrivers(void); void ide_init_disk(struct gendisk *, ide_drive_t *); From 7b4df9ece9b4c4a754bd1f5603cdabff26b987e5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:20:15 +0100 Subject: [PATCH 33/91] [PATCH] ide: cleanup ide_driver_t Remove unused fields: ioctl, ata[pi]_prebuilder. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index 613534b77054..7b6a6a58e465 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -980,10 +980,7 @@ typedef struct ide_driver_s { int (*end_request)(ide_drive_t *, int, int); ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); ide_startstop_t (*abort)(ide_drive_t *, struct request *rq); - int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); ide_proc_entry_t *proc; - void (*ata_prebuilder)(ide_drive_t *); - void (*atapi_prebuilder)(ide_drive_t *); struct device_driver gen_driver; } ide_driver_t; From 0afaa4fc4abc773ce129f41009a50eeecf3aa50c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:20:49 +0100 Subject: [PATCH 34/91] [PATCH] ide-cd: remove write-only cmd field from struct cdrom_info Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 7 ------- drivers/ide/ide-cd.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 9455e42abb23..b4d7a3efb90f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1292,7 +1292,6 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block) struct cdrom_info *info = drive->driver_data; info->dma = 0; - info->cmd = 0; info->start_seek = jiffies; return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation); } @@ -1344,8 +1343,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) (rq->nr_sectors & (sectors_per_frame - 1))) info->dma = 0; - info->cmd = READ; - /* Start sending the read request to the drive. */ return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation); } @@ -1484,7 +1481,6 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) struct cdrom_info *info = drive->driver_data; info->dma = 0; - info->cmd = 0; rq->flags &= ~REQ_FAILED; len = rq->data_len; @@ -1891,7 +1887,6 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) /* use dma, if possible. we don't need to check more, since we * know that the transfer is always (at least!) frame aligned */ info->dma = drive->using_dma ? 1 : 0; - info->cmd = WRITE; info->devinfo.media_written = 1; @@ -1916,7 +1911,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) rq->flags |= REQ_QUIET; info->dma = 0; - info->cmd = 0; /* * sg request @@ -1925,7 +1919,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) int mask = drive->queue->dma_alignment; unsigned long addr = (unsigned long) page_address(bio_page(rq->bio)); - info->cmd = rq_data_dir(rq); info->dma = drive->using_dma; /* diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 7ca3e5afc665..ad1f2ed14a37 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -480,7 +480,6 @@ struct cdrom_info { struct request request_sense_request; int dma; - int cmd; unsigned long last_block; unsigned long start_seek; /* Buffer to hold mechanism status and changer slot table. */ From c45b4f1f1e149c023762ac4be166ead1818cefef Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 14 Dec 2005 18:52:21 -0800 Subject: [PATCH 35/91] Move size optimization option outside of EMBEDDED menu, mark it EXPERIMENTAL Also, disable on sparc64 - a number of people report breakage. Probably a compiler bug, but it's quite possible that it tickles some latent kernel problem too. It still defaults to 'y' everywhere else (when enabled through EXPERIMENTAL), and Dave Jones points out that Fedora (and RHEL4) has been building with size optimizations for a long time on x86, x86-64, ia64, s390, s390x, ppc32 and ppc64. So it is really only moderately experimental, but the sparc64 breakage certainly shows that it can trigger "issues". Signed-off-by: Linus Torvalds --- init/Kconfig | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index be74adb389ea..6c5dbedc6e96 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -256,6 +256,20 @@ config CPUSETS source "usr/Kconfig" +config CC_OPTIMIZE_FOR_SIZE + bool "Optimize for size (Look out for broken compilers!)" + default y + depends on ARM || H8300 || EXPERIMENTAL + depends on !SPARC64 + help + Enabling this option will pass "-Os" instead of "-O2" to gcc + resulting in a smaller kernel. + + WARNING: some versions of gcc may generate incorrect code with this + option. If problems are observed, a gcc upgrade may be needed. + + If unsure, say N. + menuconfig EMBEDDED bool "Configure standard kernel features (for small systems)" help @@ -338,18 +352,6 @@ config EPOLL Disabling this option will cause the kernel to be built without support for epoll family of system calls. -config CC_OPTIMIZE_FOR_SIZE - bool "Optimize for size" - default y if ARM || H8300 - help - Enabling this option will pass "-Os" instead of "-O2" to gcc - resulting in a smaller kernel. - - WARNING: some versions of gcc may generate incorrect code with this - option. If problems are observed, a gcc upgrade may be needed. - - If unsure, say N. - config SHMEM bool "Use full shmem filesystem" if EMBEDDED default y From ea54c96c04cfd9fec881e403d8f7931b47f7b2a6 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Wed, 14 Dec 2005 21:47:00 -0500 Subject: [PATCH 36/91] [PATCH] Input: ALPS - correctly report button presses on Fujitsu Siemens S6010 Without this patch Forward and Backward buttons on the touchpad do not generate any events. Signed-off-by: Dmitry Torokhov Signed-off-by: Linus Torvalds --- drivers/input/mouse/alps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4acc7fd4cd0f..4f41ec3e4332 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -42,7 +42,7 @@ static struct alps_model_info alps_model_data[] = { { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, - { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 }, + { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, From 5d5e815618c4a8b53806845268c951201d14af6e Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 14 Dec 2005 14:38:36 -0500 Subject: [PATCH 37/91] [PATCH] reiserfs: skip commit on io error This should have been part of the original io error patch, but got dropped somewhere along the way. It's extremely important when handling the i/o error in the journal to not commit the transaction with corrupt data. This patch adds that code back in. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/journal.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 68b7b78638ff..3f17ef844fb6 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1039,6 +1039,10 @@ static int flush_commit_list(struct super_block *s, } atomic_dec(&journal->j_async_throttle); + /* We're skipping the commit if there's an error */ + if (retval || reiserfs_is_journal_aborted(journal)) + barrier = 0; + /* wait on everything written so far before writing the commit * if we are in barrier mode, send the commit down now */ @@ -1077,10 +1081,16 @@ static int flush_commit_list(struct super_block *s, BUG_ON(atomic_read(&(jl->j_commit_left)) != 1); if (!barrier) { - if (buffer_dirty(jl->j_commit_bh)) - BUG(); - mark_buffer_dirty(jl->j_commit_bh); - sync_dirty_buffer(jl->j_commit_bh); + /* If there was a write error in the journal - we can't commit + * this transaction - it will be invalid and, if successful, + * will just end up propogating the write error out to + * the file system. */ + if (likely(!retval && !reiserfs_is_journal_aborted (journal))) { + if (buffer_dirty(jl->j_commit_bh)) + BUG(); + mark_buffer_dirty(jl->j_commit_bh) ; + sync_dirty_buffer(jl->j_commit_bh) ; + } } else wait_on_buffer(jl->j_commit_bh); From 2499604960fff307fe99ff4d4363c50eaa69235a Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 14 Dec 2005 14:38:05 -0500 Subject: [PATCH 38/91] [PATCH] reiserfs: close open transactions on error path The following patch fixes a bug where if the journal is aborted, it can leave a transaction open. The result will be a BUG when another code path attempts to start a transaction and will get a "nesting into different fs" error, since current->journal_info will be left non-NULL. Original fix against SUSE kernel by Chris Mason Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0a044ad98885..a5e3a0ddbe53 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -32,6 +32,7 @@ void reiserfs_delete_inode(struct inode *inode) JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; + int err; truncate_inode_pages(&inode->i_data, 0); @@ -49,15 +50,13 @@ void reiserfs_delete_inode(struct inode *inode) } reiserfs_update_inode_transaction(inode); - if (reiserfs_delete_object(&th, inode)) { - up(&inode->i_sem); - goto out; - } + err = reiserfs_delete_object(&th, inode); /* Do quota update inside a transaction for journaled quotas. We must do that * after delete_object so that quota updates go into the same transaction as * stat data deletion */ - DQUOT_FREE_INODE(inode); + if (!err) + DQUOT_FREE_INODE(inode); if (journal_end(&th, inode->i_sb, jbegin_count)) { up(&inode->i_sem); @@ -66,6 +65,12 @@ void reiserfs_delete_inode(struct inode *inode) up(&inode->i_sem); + /* check return value from reiserfs_delete_object after + * ending the transaction + */ + if (err) + goto out; + /* all items of file are deleted, so we can remove "save" link */ remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything * about an error here */ @@ -2099,6 +2104,7 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) struct page *page = NULL; int error; struct buffer_head *bh = NULL; + int err2; reiserfs_write_lock(p_s_inode->i_sb); @@ -2136,14 +2142,18 @@ int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) transaction of truncating gets committed - on reboot the file either appears truncated properly or not truncated at all */ add_save_link(&th, p_s_inode, 1); - error = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps); - if (error) - goto out; + err2 = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps); error = journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1); if (error) goto out; + /* check reiserfs_do_truncate after ending the transaction */ + if (err2) { + error = err2; + goto out; + } + if (update_timestamps) { error = remove_save_link(p_s_inode, 1 /* truncate */ ); if (error) From f8ad23a401d41f90cb377035d206b41de0699a0b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:44:18 -0500 Subject: [PATCH 39/91] [PATCH] fix iomem annotations in sparc32 pcic code Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/sparc/kernel/pcic.c | 2 +- include/asm-sparc/pcic.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index cccfc12802ed..42002b742deb 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -161,7 +161,7 @@ static struct pcic_sn2list pcic_known_sysnames[] = { static int pcic0_up; static struct linux_pcic pcic0; -void * __iomem pcic_regs; +void __iomem *pcic_regs; volatile int pcic_speculative; volatile int pcic_trapped; diff --git a/include/asm-sparc/pcic.h b/include/asm-sparc/pcic.h index 301ae8022ddd..dedea14d87c8 100644 --- a/include/asm-sparc/pcic.h +++ b/include/asm-sparc/pcic.h @@ -16,10 +16,10 @@ #include struct linux_pcic { - void * __iomem pcic_regs; + void __iomem *pcic_regs; unsigned long pcic_io; - void * __iomem pcic_config_space_addr; - void * __iomem pcic_config_space_data; + void __iomem *pcic_config_space_addr; + void __iomem *pcic_config_space_data; struct resource pcic_res_regs; struct resource pcic_res_io; struct resource pcic_res_cfg_addr; From b7c690b52f424574f7ac8c607e71e9f5c283a557 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:50:56 -0500 Subject: [PATCH 40/91] [PATCH] sparc: vfc __iomem annotations and fixes Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/sbus/char/vfc.h | 2 +- drivers/sbus/char/vfc_dev.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index a7782e7da42e..8045cd5e7cb3 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h @@ -125,7 +125,7 @@ struct vfc_regs { struct vfc_dev { - volatile struct vfc_regs *regs; + volatile struct vfc_regs __iomem *regs; struct vfc_regs *phys_regs; unsigned int control_reg; struct semaphore device_lock_sem; diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 7a103698fa3c..dfdd6be551f3 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -149,7 +149,7 @@ int init_vfc_device(struct sbus_dev *sdev,struct vfc_dev *dev, int instance) } printk("Initializing vfc%d\n",instance); dev->regs = NULL; - dev->regs = (volatile struct vfc_regs *) + dev->regs = (volatile struct vfc_regs __iomem *) sbus_ioremap(&sdev->resource[0], 0, sizeof(struct vfc_regs), vfcstr); dev->which_io = sdev->reg_addrs[0].which_io; @@ -319,7 +319,7 @@ int vfc_capture_poll(struct vfc_dev *dev) int timeout = 1000; while (!timeout--) { - if (dev->regs->control & VFC_STATUS_CAPTURE) + if (sbus_readl(&dev->regs->control) & VFC_STATUS_CAPTURE) break; vfc_i2c_delay_no_busy(dev, 100); } @@ -718,7 +718,7 @@ static void deinit_vfc_device(struct vfc_dev *dev) if(dev == NULL) return; devfs_remove("vfc/%d", dev->instance); - sbus_iounmap((unsigned long)dev->regs, sizeof(struct vfc_regs)); + sbus_iounmap(dev->regs, sizeof(struct vfc_regs)); kfree(dev); } From bc05d83bbf20a32eb24624726d1027aa960a573c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:51:43 -0500 Subject: [PATCH 41/91] [PATCH] sparc: jsflash __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/sbus/char/jsflash.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index c12c5046e2fa..14631ac11bc7 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -249,11 +249,11 @@ static loff_t jsf_lseek(struct file * file, loff_t offset, int orig) /* * OS SIMM Cannot be read in other size but a 32bits word. */ -static ssize_t jsf_read(struct file * file, char * buf, +static ssize_t jsf_read(struct file * file, char __user * buf, size_t togo, loff_t *ppos) { unsigned long p = *ppos; - char *tmp = buf; + char __user *tmp = buf; union byte4 { char s[4]; @@ -305,7 +305,7 @@ static ssize_t jsf_read(struct file * file, char * buf, return tmp-buf; } -static ssize_t jsf_write(struct file * file, const char * buf, +static ssize_t jsf_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { return -ENOSPC; @@ -356,10 +356,10 @@ static int jsf_ioctl_erase(unsigned long arg) * Program a block of flash. * Very simple because we can do it byte by byte anyway. */ -static int jsf_ioctl_program(unsigned long arg) +static int jsf_ioctl_program(void __user *arg) { struct jsflash_program_arg abuf; - char *uptr; + char __user *uptr; unsigned long p; unsigned int togo; union { @@ -367,13 +367,13 @@ static int jsf_ioctl_program(unsigned long arg) char s[4]; } b; - if (copy_from_user(&abuf, (char *)arg, JSFPRGSZ)) + if (copy_from_user(&abuf, arg, JSFPRGSZ)) return -EFAULT; p = abuf.off; togo = abuf.size; if ((togo & 3) || (p & 3)) return -EINVAL; - uptr = (char *) (unsigned long) abuf.data; + uptr = (char __user *) (unsigned long) abuf.data; while (togo != 0) { togo -= 4; if (copy_from_user(&b.s[0], uptr, 4)) @@ -390,19 +390,20 @@ static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd, unsigned long arg) { int error = -ENOTTY; + void __user *argp = (void __user *)arg; if (!capable(CAP_SYS_ADMIN)) return -EPERM; switch (cmd) { case JSFLASH_IDENT: - if (copy_to_user((void *)arg, &jsf0.id, JSFIDSZ)) + if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) return -EFAULT; break; case JSFLASH_ERASE: error = jsf_ioctl_erase(arg); break; case JSFLASH_PROGRAM: - error = jsf_ioctl_program(arg); + error = jsf_ioctl_program(argp); break; } From fec607fff973b1d7805c1bbce5834690857e7801 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:54:54 -0500 Subject: [PATCH 42/91] [PATCH] sbus/char/uctrl: missing prototypes and NULL noise removal Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/sbus/char/uctrl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index 858cc683f85c..e2d9a7c85427 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -309,7 +309,7 @@ static void uctrl_do_txn(struct uctrl_txn *txn) } } -void uctrl_get_event_status() +void uctrl_get_event_status(void) { struct uctrl_driver *driver = &drv; struct uctrl_txn txn; @@ -318,7 +318,7 @@ void uctrl_get_event_status() txn.opcode = READ_EVENT_STATUS; txn.inbits = 0; txn.outbits = 2; - txn.inbuf = 0; + txn.inbuf = NULL; txn.outbuf = outbits; uctrl_do_txn(&txn); @@ -329,7 +329,7 @@ void uctrl_get_event_status() dprintk(("ev is %x\n", driver->status.event_status)); } -void uctrl_get_external_status() +void uctrl_get_external_status(void) { struct uctrl_driver *driver = &drv; struct uctrl_txn txn; @@ -339,7 +339,7 @@ void uctrl_get_external_status() txn.opcode = READ_EXTERNAL_STATUS; txn.inbits = 0; txn.outbits = 2; - txn.inbuf = 0; + txn.inbuf = NULL; txn.outbuf = outbits; uctrl_do_txn(&txn); @@ -414,7 +414,7 @@ static void __exit ts102_uctrl_cleanup(void) if (driver->irq) free_irq(driver->irq, driver); if (driver->regs) - driver->regs = 0; + driver->regs = NULL; } module_init(ts102_uctrl_init); From c316ef0494eec2d08df2f083fc06fc06a6fd48c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:55:44 -0500 Subject: [PATCH 43/91] [PATCH] sparc/kernel/time: __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/sparc/kernel/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 24814d58f9e1..7dadcdb4ca42 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -49,7 +49,7 @@ DEFINE_SPINLOCK(rtc_lock); enum sparc_clock_type sp_clock_typ; DEFINE_SPINLOCK(mostek_lock); void __iomem *mstk48t02_regs = NULL; -static struct mostek48t08 *mstk48t08_regs = NULL; +static struct mostek48t08 __iomem *mstk48t08_regs = NULL; static int set_rtc_mmss(unsigned long); static int sbus_do_settimeofday(struct timespec *tv); @@ -342,7 +342,7 @@ static __inline__ void clock_probe(void) /* XXX r/o attribute is somewhere in r.flags */ r.flags = clk_reg[0].which_io; r.start = clk_reg[0].phys_addr; - mstk48t08_regs = (struct mostek48t08 *) sbus_ioremap(&r, 0, + mstk48t08_regs = sbus_ioremap(&r, 0, sizeof(struct mostek48t08), "mk48t08"); mstk48t02_regs = &mstk48t08_regs->regs; From e4fe342f932346a306f98f5401ad510b890c0a15 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 4 Dec 2005 18:48:45 -0500 Subject: [PATCH 44/91] [PATCH] sparc: NULL noise removal (ebus.c) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/sparc/kernel/ebus.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index 1754192c69d0..5c3529ceb5d6 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -22,7 +22,7 @@ #include #include -struct linux_ebus *ebus_chain = 0; +struct linux_ebus *ebus_chain = NULL; /* We are together with pcic.c under CONFIG_PCI. */ extern unsigned int pcic_pin_to_irq(unsigned int, char *name); @@ -46,7 +46,7 @@ static struct ebus_device_irq je1_1[] = { { "SUNW,CS4231", 0 }, { "parallel", 0 }, { "se", 2 }, - { 0, 0 } + { NULL, 0 } }; /* @@ -55,7 +55,7 @@ static struct ebus_device_irq je1_1[] = { */ static struct ebus_system_entry ebus_blacklist[] = { { "SUNW,JavaEngine1", je1_1 }, - { 0, 0 } + { NULL, NULL } }; static struct ebus_device_irq *ebus_blackp = NULL; @@ -233,7 +233,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev) ebus_alloc(sizeof(struct linux_ebus_child)); child = dev->children; - child->next = 0; + child->next = NULL; child->parent = dev; child->bus = dev->bus; fill_ebus_child(node, ®s[0], child); @@ -243,7 +243,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev) ebus_alloc(sizeof(struct linux_ebus_child)); child = child->next; - child->next = 0; + child->next = NULL; child->parent = dev; child->bus = dev->bus; fill_ebus_child(node, ®s[0], child); @@ -275,7 +275,7 @@ void __init ebus_init(void) } } - pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0); + pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL); if (!pdev) { return; } @@ -284,7 +284,7 @@ void __init ebus_init(void) ebus_chain = ebus = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); - ebus->next = 0; + ebus->next = NULL; while (ebusnd) { @@ -325,8 +325,8 @@ void __init ebus_init(void) ebus_alloc(sizeof(struct linux_ebus_device)); dev = ebus->devices; - dev->next = 0; - dev->children = 0; + dev->next = NULL; + dev->children = NULL; dev->bus = ebus; fill_ebus_device(nd, dev); @@ -335,8 +335,8 @@ void __init ebus_init(void) ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; - dev->next = 0; - dev->children = 0; + dev->next = NULL; + dev->children = NULL; dev->bus = ebus; fill_ebus_device(nd, dev); } @@ -353,7 +353,7 @@ void __init ebus_init(void) ebus->next = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; - ebus->next = 0; + ebus->next = NULL; ++num_ebus; } if (pdev) From a32972965e23471f0762a1136f80990ebf72406a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:56:39 -0500 Subject: [PATCH 45/91] [PATCH] sun4c_memerr_reg __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/sparc/mm/sun4c.c | 2 +- include/asm-sparc/memreg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 1d560390e282..731f19603cad 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -497,7 +497,7 @@ static void __init sun4c_probe_mmu(void) patch_kernel_fault_handler(); } -volatile unsigned long *sun4c_memerr_reg = NULL; +volatile unsigned long __iomem *sun4c_memerr_reg = NULL; void __init sun4c_probe_memerr_reg(void) { diff --git a/include/asm-sparc/memreg.h b/include/asm-sparc/memreg.h index c0498d3baf93..5fb95c828da6 100644 --- a/include/asm-sparc/memreg.h +++ b/include/asm-sparc/memreg.h @@ -36,7 +36,7 @@ /* Memory parity error register with associated bit constants. */ #ifndef __ASSEMBLY__ -extern __volatile__ unsigned long *sun4c_memerr_reg; +extern __volatile__ unsigned long __iomem *sun4c_memerr_reg; #endif #define SUN4C_MPE_ERROR 0x80 /* Parity error detected. (ro) */ From 80ce8baf5da730c87194e2e38a4cfca0254f9599 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 06:04:55 -0500 Subject: [PATCH 46/91] [PATCH] arch/sparc/kernel/led.c __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/sparc/kernel/led.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 2a3afca453c9..313d1620ae8e 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -55,7 +55,7 @@ static int led_read_proc(char *buf, char **start, off_t offset, int count, return len; } -static int led_write_proc(struct file *file, const char *buffer, +static int led_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data) { char *buf = NULL; From b53cb2a4ab276796ad299597d6e7e2317b514ca8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:19 +0000 Subject: [PATCH 47/91] [PATCH] iscsi gfp_t annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/scsi/iscsi_tcp.c | 2 +- drivers/scsi/scsi_transport_iscsi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 4fea3e4edaa7..3d8009f55342 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3368,7 +3368,7 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: { char *saveptr = conn->data; - int flags = GFP_KERNEL; + gfp_t flags = GFP_KERNEL; if (conn->data_size >= value) { conn->max_recv_dlength = value; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 49fd18c1a9c6..e08462d50c97 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -249,7 +249,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) } static void* -mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) +mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) { struct mempool_zone *zone = pool_data; From 51bfb75b0b2652f60ab1200627e9041f4624c819 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:24 +0000 Subject: [PATCH 48/91] [PATCH] xfs: missing gfp_t annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- fs/xfs/quota/xfs_qm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 1aea42d71a64..5328a2937127 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -78,7 +78,7 @@ STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *); STATIC int xfs_qm_init_quotainos(xfs_mount_t *); STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); -STATIC int xfs_qm_shake(int, unsigned int); +STATIC int xfs_qm_shake(int, gfp_t); #ifdef DEBUG extern mutex_t qcheck_lock; @@ -2197,7 +2197,7 @@ xfs_qm_shake_freelist( */ /* ARGSUSED */ STATIC int -xfs_qm_shake(int nr_to_scan, unsigned int gfp_mask) +xfs_qm_shake(int nr_to_scan, gfp_t gfp_mask) { int ndqused, nfree, n; From 37eb47ed445f4ca1247f3c7b600c0885c2ca8c31 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:29 +0000 Subject: [PATCH 49/91] [PATCH] s2io: __iomem annotations for recent changes Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/s2io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e57df8dfe6b4..669dd52c412a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -3078,7 +3078,7 @@ int s2io_set_swapper(nic_t * sp) static int wait_for_msix_trans(nic_t *nic, int i) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int ret = 0, cnt = 0; @@ -3099,7 +3099,7 @@ static int wait_for_msix_trans(nic_t *nic, int i) void restore_xmsi_data(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; int i; @@ -3117,7 +3117,7 @@ void restore_xmsi_data(nic_t *nic) static void store_xmsi_data(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64, addr, data; int i; @@ -3140,7 +3140,7 @@ static void store_xmsi_data(nic_t *nic) int s2io_enable_msi(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u16 msi_ctrl, msg_val; struct config_param *config = &nic->config; struct net_device *dev = nic->dev; @@ -3190,7 +3190,7 @@ int s2io_enable_msi(nic_t *nic) int s2io_enable_msi_x(nic_t *nic) { - XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; + XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 tx_mat, rx_mat; u16 msi_control; /* Temp variable */ int ret, i, j, msix_indx = 1; From 53b3de1ea2f81de7050f247cd7fc63863887e8d7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:34 +0000 Subject: [PATCH 50/91] [PATCH] auerswald.c: %zd for size_t Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/usb/misc/auerswald.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 2a28ceeaa66a..b293db3c28c3 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c @@ -1696,7 +1696,7 @@ static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t int ret; wait_queue_t wait; - dbg ("auerchar_write %d bytes", len); + dbg ("auerchar_write %zd bytes", len); /* Error checking */ if (!ccp) From 8bcc247617deaf229962e9d663c69e65523519ab Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:39 +0000 Subject: [PATCH 51/91] [PATCH] em28xx: %zd for size_t Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/media/video/em28xx/em28xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index e8a1c2247567..ec11619f8ea9 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -126,7 +126,7 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ void *buff = NULL; u32 i; - em28xx_coredbg("requested %i buffers with size %i", count, imagesize); + em28xx_coredbg("requested %i buffers with size %zd", count, imagesize); if (count > EM28XX_NUM_FRAMES) count = EM28XX_NUM_FRAMES; From 8b8a4e33e4a320735f353a092013b314f142493d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:44 +0000 Subject: [PATCH 52/91] [PATCH] i386,amd64: mmconfig __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/i386/pci/mmconfig.c | 2 +- arch/x86_64/pci/mmconfig.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 08a084901212..70a9cc132cf7 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -155,7 +155,7 @@ static __init void unreachable_devices(void) addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); if (addr != 0) pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); - if (addr == 0 || readl((u32 *)addr) != val1) + if (addr == 0 || readl((u32 __iomem *)addr) != val1) set_bit(i, fallback_slots); spin_unlock_irqrestore(&pci_config_lock, flags); } diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 9c4f907e301c..f16c0d57c552 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -18,11 +18,11 @@ static DECLARE_BITMAP(fallback_slots, 32); /* Static virtual mapping of the MMCONFIG aperture */ struct mmcfg_virt { struct acpi_table_mcfg_config *cfg; - char *virt; + char __iomem *virt; }; static struct mmcfg_virt *pci_mmcfg_virt; -static char *get_virt(unsigned int seg, unsigned bus) +static char __iomem *get_virt(unsigned int seg, unsigned bus) { int cfg_num = -1; struct acpi_table_mcfg_config *cfg; @@ -43,9 +43,9 @@ static char *get_virt(unsigned int seg, unsigned bus) } } -static char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { - char *addr; + char __iomem *addr; if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots)) return NULL; addr = get_virt(seg, bus); @@ -57,7 +57,7 @@ static char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr; + char __iomem *addr; /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) @@ -85,7 +85,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { - char *addr; + char __iomem *addr; /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) @@ -127,7 +127,7 @@ static __init void unreachable_devices(void) int i; for (i = 0; i < 32; i++) { u32 val1; - char *addr; + char __iomem *addr; pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1); if (val1 == 0xffffffff) From b16b88e55d808a6324d5ff02d8c686f7884870f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:50 +0000 Subject: [PATCH 53/91] [PATCH] i386,amd64: ioremap.c __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/i386/mm/ioremap.c | 2 +- arch/x86_64/mm/ioremap.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 8498b5ac3955..247fde76aaed 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -245,7 +245,7 @@ void iounmap(volatile void __iomem *addr) addr < phys_to_virt(ISA_END_ADDRESS)) return; - addr = (volatile void *)(PAGE_MASK & (unsigned long __force)addr); + addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr); /* Use the vm area unlocked, assuming the caller ensures there isn't another iounmap for the same address diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index 0d260e4492f7..ae207064201e 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c @@ -263,7 +263,7 @@ void iounmap(volatile void __iomem *addr) addr < phys_to_virt(ISA_END_ADDRESS)) return; - addr = (volatile void *)(PAGE_MASK & (unsigned long __force)addr); + addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr); /* Use the vm area unlocked, assuming the caller ensures there isn't another iounmap for the same address in parallel. Reuse of the virtual address is prevented by From c4aa02eb3939c5004782454434e4d50de471b53d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:55 +0000 Subject: [PATCH 54/91] [PATCH] cm4000_cs: __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/pcmcia/cm4000_cs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index ef011ef5dc46..61681c9f3f72 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1444,6 +1444,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, dev_link_t *link; int size; int rc; + void __user *argp = (void __user *)arg; #ifdef PCMCIA_DEBUG char *ioctl_names[CM_IOC_MAXNR + 1] = { [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", @@ -1481,11 +1482,11 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd); if (_IOC_DIR(cmd) & _IOC_READ) { - if (!access_ok(VERIFY_WRITE, (void *)arg, size)) + if (!access_ok(VERIFY_WRITE, argp, size)) return -EFAULT; } if (_IOC_DIR(cmd) & _IOC_WRITE) { - if (!access_ok(VERIFY_READ, (void *)arg, size)) + if (!access_ok(VERIFY_READ, argp, size)) return -EFAULT; } @@ -1506,14 +1507,14 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, status |= CM_NO_READER; if (test_bit(IS_BAD_CARD, &dev->flags)) status |= CM_BAD_CARD; - if (copy_to_user((int *)arg, &status, sizeof(int))) + if (copy_to_user(argp, &status, sizeof(int))) return -EFAULT; } return 0; case CM_IOCGATR: DEBUGP(4, dev, "... in CM_IOCGATR\n"); { - struct atreq *atreq = (struct atreq *) arg; + struct atreq __user *atreq = argp; int tmp; /* allow nonblocking io and being interrupted */ if (wait_event_interruptible @@ -1597,7 +1598,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, { struct ptsreq krnptsreq; - if (copy_from_user(&krnptsreq, (struct ptsreq *) arg, + if (copy_from_user(&krnptsreq, argp, sizeof(struct ptsreq))) return -EFAULT; @@ -1641,7 +1642,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, int old_pc_debug = 0; old_pc_debug = pc_debug; - if (copy_from_user(&pc_debug, (int *)arg, sizeof(int))) + if (copy_from_user(&pc_debug, argp, sizeof(int))) return -EFAULT; if (old_pc_debug != pc_debug) From 5ad9201be7f7d52d712fe3c3e841fdc19216ede1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:00 +0000 Subject: [PATCH 55/91] [PATCH] dell_rbu: NULL noise removal Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/firmware/dell_rbu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index 6d83299e7c9b..dfedb777d8c9 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -105,8 +105,8 @@ static int create_packet(void *data, size_t length) int ordernum = 0; int retval = 0; unsigned int packet_array_size = 0; - void **invalid_addr_packet_array = 0; - void *packet_data_temp_buf = 0; + void **invalid_addr_packet_array = NULL; + void *packet_data_temp_buf = NULL; unsigned int idx = 0; pr_debug("create_packet: entry \n"); @@ -178,7 +178,7 @@ static int create_packet(void *data, size_t length) packet_data_temp_buf), allocation_floor); invalid_addr_packet_array[idx++] = packet_data_temp_buf; - packet_data_temp_buf = 0; + packet_data_temp_buf = NULL; } } spin_lock(&rbu_data.lock); From e896fd9861181140617aa9ff3a54dac25e46351d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:05 +0000 Subject: [PATCH 56/91] [PATCH] wdrtas.c: fix __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/watchdog/wdrtas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c index 619e2ffca33f..dacfe31caccf 100644 --- a/drivers/char/watchdog/wdrtas.c +++ b/drivers/char/watchdog/wdrtas.c @@ -320,7 +320,7 @@ static int wdrtas_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int __user *argp = (void *)arg; + int __user *argp = (void __user *)arg; int i; static struct watchdog_info wdinfo = { .options = WDRTAS_SUPPORTED_MASK, From cd0306656c15f355e0e533cc0f08691bb98ca912 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:10 +0000 Subject: [PATCH 57/91] [PATCH] cyber2000fb.c __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/video/cyber2000fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index c589d23e7f91..a9300f930ef2 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -1512,7 +1512,7 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb) * I/O cycles storing into a reserved memory space at * physical address 0x3000000 */ - unsigned char *iop; + unsigned char __iomem *iop; iop = ioremap(0x3000000, 0x5000); if (iop == NULL) { @@ -1526,7 +1526,7 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb) writeb(EXT_BIU_MISC, iop + 0x3ce); writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf); - iounmap((void *)iop); + iounmap(iop); #else /* * Most other machine types are "normal", so From d22043940eb8d660df9a94e8e439ab4d3d16edab Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:15 +0000 Subject: [PATCH 58/91] [PATCH] arcfb __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/video/arcfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 080db812ca48..2784f0a9d693 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -441,7 +441,7 @@ static int arcfb_ioctl(struct inode *inode, struct file *file, * the fb. it's inefficient for them to do anything less than 64*8 * writes since we update the lcd in each write() anyway. */ -static ssize_t arcfb_write(struct file *file, const char *buf, size_t count, +static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { /* modded from epson 1355 */ From 538bacf8a4802d209f955726b66891b8a921dabf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:20 +0000 Subject: [PATCH 59/91] [PATCH] __user annotations (booke_wdt.c) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/watchdog/booke_wdt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index 65830ec71042..c800cce73c1e 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c @@ -72,7 +72,7 @@ static __inline__ void booke_wdt_ping(void) /* * booke_wdt_write: */ -static ssize_t booke_wdt_write (struct file *file, const char *buf, +static ssize_t booke_wdt_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos) { booke_wdt_ping(); @@ -92,14 +92,15 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { u32 tmp = 0; + u32 __user *p = (u32 __user *)arg; switch (cmd) { case WDIOC_GETSUPPORT: - if (copy_to_user ((struct watchdog_info *) arg, &ident, + if (copy_to_user ((struct watchdog_info __user *) arg, &ident, sizeof(struct watchdog_info))) return -EFAULT; case WDIOC_GETSTATUS: - return put_user(ident.options, (u32 *) arg); + return put_user(ident.options, p); case WDIOC_GETBOOTSTATUS: /* XXX: something is clearing TSR */ tmp = mfspr(SPRN_TSR) & TSR_WRS(3); @@ -109,14 +110,14 @@ static int booke_wdt_ioctl (struct inode *inode, struct file *file, booke_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(booke_wdt_period, (u32 *) arg)) + if (get_user(booke_wdt_period, p)) return -EFAULT; mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period)); return 0; case WDIOC_GETTIMEOUT: - return put_user(booke_wdt_period, (u32 *) arg); + return put_user(booke_wdt_period, p); case WDIOC_SETOPTIONS: - if (get_user(tmp, (u32 *) arg)) + if (get_user(tmp, p)) return -EINVAL; if (tmp == WDIOS_ENABLECARD) { booke_wdt_ping(); From 78d9955bb06493e7bd78e43dfdc17fb5f1dc59b6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:25 +0000 Subject: [PATCH 60/91] [PATCH] missing prototype (mm/page_alloc.c) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3b21a13d841c..fe14a8c87fc2 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1896,7 +1896,7 @@ static int __devinit pageset_cpuup_callback(struct notifier_block *nfb, static struct notifier_block pageset_notifier = { &pageset_cpuup_callback, NULL, 0 }; -void __init setup_per_cpu_pageset() +void __init setup_per_cpu_pageset(void) { int err; From d3a880e1ff6713b4c846e4d2526a8c7e6ad8469c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:30 +0000 Subject: [PATCH 61/91] [PATCH] Address of void __user * is void __user * *, not void * __user * Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- net/sctp/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d890dfa8818f..1f7f244806b7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3425,7 +3425,7 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add } static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, - void * __user *to, size_t space_left) + void __user **to, size_t space_left) { struct list_head *pos; struct sctp_sockaddr_entry *addr; From b3e5b5b2277f9c047082dcb309f665fe8b5706c1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:40 +0000 Subject: [PATCH 62/91] [PATCH] ia64 sn __iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/ia64/sn/pci/pcibr/pcibr_reg.c | 48 +++++++++++++++--------------- arch/ia64/sn/pci/tioca_provider.c | 12 ++++---- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 5d534091262c..79fdb91d7259 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c @@ -25,7 +25,7 @@ union br_ptr { */ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -38,14 +38,14 @@ void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) default: panic ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -58,7 +58,7 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) default: panic ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } @@ -68,7 +68,7 @@ void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) */ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; uint64_t ret = 0; if (pcibus_info) { @@ -82,7 +82,7 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) default: panic ("pcireg_tflush_get: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } @@ -98,7 +98,7 @@ uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info) */ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; uint64_t ret = 0; if (pcibus_info) { @@ -112,7 +112,7 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) default: panic ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } return ret; @@ -123,7 +123,7 @@ uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info) */ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -136,14 +136,14 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) default: panic ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -156,7 +156,7 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) default: panic ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } @@ -167,7 +167,7 @@ void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits) void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, uint64_t addr) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -186,7 +186,7 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, default: panic ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } @@ -196,7 +196,7 @@ void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, */ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -209,7 +209,7 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) default: panic ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } @@ -219,7 +219,7 @@ void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) */ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; uint64_t ret = 0; if (pcibus_info) { @@ -233,7 +233,7 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]); break; default: - panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr); + panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr); } } @@ -244,7 +244,7 @@ uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, uint64_t val) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -257,15 +257,15 @@ void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, default: panic ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } } -uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) +uint64_t __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) { - union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base; - uint64_t *ret = (uint64_t *) 0; + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + uint64_t __iomem *ret = NULL; if (pcibus_info) { switch (pcibus_info->pbi_bridge_type) { @@ -278,7 +278,7 @@ uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) default: panic ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p", - (void *)ptr); + ptr); } } return ret; diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 46b646a6d345..27aa1842dacc 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -38,10 +38,10 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) uint64_t offset; struct page *tmp; struct tioca_common *tioca_common; - struct tioca *ca_base; + struct tioca __iomem *ca_base; tioca_common = tioca_kern->ca_common; - ca_base = (struct tioca *)tioca_common->ca_common.bs_base; + ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base; if (list_empty(tioca_kern->ca_devices)) return 0; @@ -215,7 +215,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) { int cap_ptr; uint32_t reg; - struct tioca *tioca_base; + struct tioca __iomem *tioca_base; struct pci_dev *pdev; struct tioca_common *common; @@ -257,7 +257,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern) * Set ca's fw to match */ - tioca_base = (struct tioca *)common->ca_common.bs_base; + tioca_base = (struct tioca __iomem*)common->ca_common.bs_base; __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE); } @@ -322,7 +322,7 @@ static uint64_t tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) { struct tioca_common *tioca_common; - struct tioca *ca_base; + struct tioca __iomem *ca_base; uint64_t ct_addr; dma_addr_t bus_addr; uint32_t node_upper; @@ -330,7 +330,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev); tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info; - ca_base = (struct tioca *)tioca_common->ca_common.bs_base; + ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base; ct_addr = PHYS_TO_TIODMA(paddr); if (!ct_addr) From 94299171dd269aab0c97f6254cedb381f10e6348 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:45 +0000 Subject: [PATCH 63/91] [PATCH] dst_ca __user annotations, portability fixes Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst_ca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index e6541aff3996..2239651969c8 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c @@ -406,7 +406,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, } dprintk(verbose, DST_CA_DEBUG, 1, " "); - if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) { + if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) { result = -EFAULT; goto free_mem_and_exit; } @@ -579,7 +579,7 @@ static int dst_ca_release(struct inode *inode, struct file *file) return 0; } -static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) +static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) { int bytes_read = 0; @@ -588,7 +588,7 @@ static int dst_ca_read(struct file *file, char __user *buffer, size_t length, lo return bytes_read; } -static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) +static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) { dprintk(verbose, DST_CA_DEBUG, 1, " Device write."); From e17f008bbeabcd1302d6cf4b5b9659be6d80f1db Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:50 +0000 Subject: [PATCH 64/91] [PATCH] arch/alpha/kernel/machvec_impl.h: C99 struct initializer Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/alpha/kernel/machvec_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index 4959b7a3e1e6..11f996f24fde 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -41,7 +41,7 @@ #define CAT1(x,y) x##y #define CAT(x,y) CAT1(x,y) -#define DO_DEFAULT_RTC rtc_port: 0x70 +#define DO_DEFAULT_RTC .rtc_port = 0x70 #define DO_EV4_MMU \ .max_asn = EV4_MAX_ASN, \ From 7877327d9c360ac91f22e4c7f98bcb10c0180969 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:55 +0000 Subject: [PATCH 65/91] [PATCH] drivers/atm/adummy.c NULL noise removal Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/atm/adummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index d15c194be44a..d1387cfe2d30 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -123,7 +123,7 @@ static int __init adummy_init(void) } memset(adummy_dev, 0, sizeof(struct adummy_dev)); - atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, 0); + atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL); if (!atm_dev) { printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); err = -ENODEV; From 833882b452046d3d5028f6293a0a6d6d3c1eee3c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:00 +0000 Subject: [PATCH 66/91] [PATCH] mwave: missing __user in ioctl struct declaration Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/mwave/mwavepub.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h index f1f9da7a65c1..60c961ae23b4 100644 --- a/drivers/char/mwave/mwavepub.h +++ b/drivers/char/mwave/mwavepub.h @@ -69,7 +69,7 @@ typedef struct _MW_ABILITIES { typedef struct _MW_READWRITE { unsigned short usDspAddress; /* The dsp address */ unsigned long ulDataLength; /* The size in bytes of the data or user buffer */ - void *pBuf; /* Input:variable sized buffer */ + void __user *pBuf; /* Input:variable sized buffer */ } MW_READWRITE, *pMW_READWRITE; #define IOCTL_MW_RESET _IO(MWAVE_MINOR,1) From 81f0a91e8f58a7784afe39cda9ac47e9231412a4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:05 +0000 Subject: [PATCH 67/91] [PATCH] drivers/input/misc/wistron_btns.c NULL noise removal Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/input/misc/wistron_btns.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 49d0416a2a9a..bac3085185fe 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -320,7 +320,7 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_acer_aspire_1500 }, - { 0, } + { NULL, } }; static int __init select_keymap(void) From ebbd1bce79b3b4778d9e1914a22c42fcfa869cd9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:10 +0000 Subject: [PATCH 68/91] [PATCH] arch/powerpc/kernel/syscalls.c __user annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/syscalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c index f72ced11212d..91b93d917b64 100644 --- a/arch/powerpc/kernel/syscalls.c +++ b/arch/powerpc/kernel/syscalls.c @@ -247,7 +247,7 @@ long ppc64_personality(unsigned long personality) #define OVERRIDE_MACHINE 0 #endif -static inline int override_machine(char *mach) +static inline int override_machine(char __user *mach) { if (OVERRIDE_MACHINE) { /* change ppc64 to ppc */ From 7767e126ca0f32cd0438455fdd9650f909d2eeb3 Mon Sep 17 00:00:00 2001 From: Paolo Galtieri Date: Thu, 15 Dec 2005 12:34:28 -0800 Subject: [PATCH 69/91] [PATCH] IPMI oops fix While doing some testing I discovered that if the BIOS on a board does not properly setup the DMI information it leads to a panic in the IPMI code. The panic is due to dereferencing a pointer which is not initialized. The pointer is initialized in port_setup() and/or mem_setup() and used in init_one_smi() and cleanup_one_si(), however if either port_setup() or mem_setup() return ENODEV the pointer does not get initialized. Signed-off-by: Paolo Galtieri Acked-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 01a1f6badb53..beea450ee4b2 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2399,7 +2399,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi) new_smi->handlers->cleanup(new_smi->si_sm); kfree(new_smi->si_sm); } - new_smi->io_cleanup(new_smi); + if (new_smi->io_cleanup) + new_smi->io_cleanup(new_smi); return rv; } @@ -2518,7 +2519,8 @@ static void __exit cleanup_one_si(struct smi_info *to_clean) kfree(to_clean->si_sm); - to_clean->io_cleanup(to_clean); + if (to_clean->io_cleanup) + to_clean->io_cleanup(to_clean); } static __exit void cleanup_ipmi_si(void) From 2f40fb72a2121da44c35f2588ee9abce1dffa2a9 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 15 Dec 2005 12:34:29 -0800 Subject: [PATCH 70/91] [PATCH] drivers/base/memory.c: unexport the static (sic) memory_sysdev_class We can't export a static struct to modules. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/memory.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index b7ddd651d664..bc3ca6a656b2 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -28,7 +28,6 @@ static struct sysdev_class memory_sysdev_class = { set_kset_name(MEMORY_CLASS_NAME), }; -EXPORT_SYMBOL(memory_sysdev_class); static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj) { From 7b6666530e2736f190a2629c8abe34275054449f Mon Sep 17 00:00:00 2001 From: Sergei Shtylylov Date: Thu, 15 Dec 2005 12:34:30 -0800 Subject: [PATCH 71/91] [PATCH] Au1550 AC'97 OSS driver spinlock fixes We have found some issues with Au1550 AC'97 OSS driver in 2.6 (sound/oss/au1550_ac97.c), though it also should concern 2.4 driver (drivers/sound/au1550_psc.c). start_dac() grabs a spinlock already held by its caller, au1550_write(). This doesn't show up with the standard UP spinlock impelmentation but when the different one (mutex based) is in use, a lockup happens. And the interrupt handlers also didn't grab the spinlock -- that's OK in the usual kernel but not when the IRQ handlers are threaded. So, they're grabbing the spinlock now (as every correct interrupt handler should do). Signed-off-by: Konstantin Baidarov Signed-off-by: Sergei Shtylyov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/oss/au1550_ac97.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index 6b46a8a4b1cc..b963c550dae6 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -578,17 +578,15 @@ set_recv_slots(int num_channels) } while ((stat & PSC_AC97STAT_DR) == 0); } +/* Hold spinlock for both start_dac() and start_adc() calls */ static void start_dac(struct au1550_state *s) { struct dmabuf *db = &s->dma_dac; - unsigned long flags; if (!db->stopped) return; - spin_lock_irqsave(&s->lock, flags); - set_xmit_slots(db->num_channels); au_writel(PSC_AC97PCR_TC, PSC_AC97PCR); au_sync(); @@ -598,8 +596,6 @@ start_dac(struct au1550_state *s) au1xxx_dbdma_start(db->dmanr); db->stopped = 0; - - spin_unlock_irqrestore(&s->lock, flags); } static void @@ -718,7 +714,6 @@ prog_dmabuf_dac(struct au1550_state *s) } -/* hold spinlock for the following */ static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -726,6 +721,8 @@ dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct dmabuf *db = &s->dma_dac; u32 ac97c_stat; + spin_lock(&s->lock); + ac97c_stat = au_readl(PSC_AC97STAT); if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) pr_debug("AC97C status = 0x%08x\n", ac97c_stat); @@ -747,6 +744,8 @@ dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* wake up anybody listening */ if (waitqueue_active(&db->wait)) wake_up(&db->wait); + + spin_unlock(&s->lock); } @@ -758,6 +757,8 @@ adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) u32 obytes; char *obuf; + spin_lock(&s->lock); + /* Pull the buffer from the dma queue. */ au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes); @@ -765,6 +766,7 @@ adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((dp->count + obytes) > dp->dmasize) { /* Overrun. Stop ADC and log the error */ + spin_unlock(&s->lock); stop_adc(s); dp->error++; err("adc overrun"); @@ -787,6 +789,7 @@ adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (waitqueue_active(&dp->wait)) wake_up(&dp->wait); + spin_unlock(&s->lock); } static loff_t @@ -1048,9 +1051,9 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) /* wait for samples in ADC dma buffer */ do { + spin_lock_irqsave(&s->lock, flags); if (db->stopped) start_adc(s); - spin_lock_irqsave(&s->lock, flags); avail = db->count; if (avail <= 0) __set_current_state(TASK_INTERRUPTIBLE); @@ -1570,15 +1573,19 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd, if (get_user(val, (int *) arg)) return -EFAULT; if (file->f_mode & FMODE_READ) { - if (val & PCM_ENABLE_INPUT) + if (val & PCM_ENABLE_INPUT) { + spin_lock_irqsave(&s->lock, flags); start_adc(s); - else + spin_unlock_irqrestore(&s->lock, flags); + } else stop_adc(s); } if (file->f_mode & FMODE_WRITE) { - if (val & PCM_ENABLE_OUTPUT) + if (val & PCM_ENABLE_OUTPUT) { + spin_lock_irqsave(&s->lock, flags); start_dac(s); - else + spin_unlock_irqrestore(&s->lock, flags); + } else stop_dac(s); } return 0; From 281ab031a8c9e5b593142eb4ec59a87faae8676a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 16 Dec 2005 16:52:22 +1100 Subject: [PATCH 72/91] [PATCH] radeon drm: fix agp aperture map offset This finally fixes the radeon memory mapping bug that was incorrectly fixed by the previous patch. This time, we use the actual vram size as the size to calculate how far to move the AGP aperture from the framebuffer in card's memory space. If there are still issues with this patch, they are due to bugs in the X driver that I'm working on fixing too. Signed-off-by: Benjamin Herrenschmidt Cc: Mark M. Hoffman Cc: Paul Mackerras Signed-off-by: Linus Torvalds --- drivers/char/drm/radeon_cp.c | 9 +++++++-- drivers/char/drm/radeon_drv.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 9f2b4efd0c7a..95ae9e0892ac 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -1312,6 +1312,8 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private;; + unsigned int mem_size; + DRM_DEBUG("\n"); dev_priv->is_pci = init->is_pci; @@ -1521,8 +1523,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) + dev_priv->fb_location) >> 10)); dev_priv->gart_size = init->gart_size; - dev_priv->gart_vm_start = dev_priv->fb_location - + RADEON_READ(RADEON_CONFIG_APER_SIZE) * 2; + + mem_size = RADEON_READ(RADEON_CONFIG_MEMSIZE); + if (mem_size == 0) + mem_size = 0x800000; + dev_priv->gart_vm_start = dev_priv->fb_location + mem_size; #if __OS_HAS_AGP if (!dev_priv->is_pci) diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 7bda7e33d2bd..d92ccee3e54c 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h @@ -379,6 +379,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, # define RADEON_PLL_WR_EN (1 << 7) #define RADEON_CLOCK_CNTL_INDEX 0x0008 #define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CONFIG_MEMSIZE 0x00f8 #define RADEON_CRTC_OFFSET 0x0224 #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_EN (1 << 15) From f5899b5d4fa806403f547dc41312d017d94ec273 Mon Sep 17 00:00:00 2001 From: John Hawkes Date: Fri, 16 Dec 2005 10:00:24 -0800 Subject: [PATCH 73/91] [IA64] disable preemption in udelay() The udelay() inline for ia64 uses the ITC. If CONFIG_PREEMPT is enabled and the platform has unsynchronized ITCs and the calling task migrates to another CPU while doing the udelay loop, then the effective delay may be too short or very, very long. This patch disables preemption around 100 usec chunks of the overall desired udelay time. This minimizes preemption-holdoffs. udelay() is now too big to be inline, move it out of line and export it. Signed-off-by: John Hawkes Signed-off-by: Tony Luck --- arch/ia64/kernel/time.c | 29 +++++++++++++++++++++++++++++ include/asm-ia64/delay.h | 10 +--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 5b7e736f3b49..028a2b95936c 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -249,3 +249,32 @@ time_init (void) */ set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); } + +#define SMALLUSECS 100 + +void +udelay (unsigned long usecs) +{ + unsigned long start; + unsigned long cycles; + unsigned long smallusecs; + + /* + * Execute the non-preemptible delay loop (because the ITC might + * not be synchronized between CPUS) in relatively short time + * chunks, allowing preemption between the chunks. + */ + while (usecs > 0) { + smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs; + preempt_disable(); + cycles = smallusecs*local_cpu_data->cyc_per_usec; + start = ia64_get_itc(); + + while (ia64_get_itc() - start < cycles) + cpu_relax(); + + preempt_enable(); + usecs -= smallusecs; + } +} +EXPORT_SYMBOL(udelay); diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h index 57182d6f2b9a..bba702076391 100644 --- a/include/asm-ia64/delay.h +++ b/include/asm-ia64/delay.h @@ -84,14 +84,6 @@ __delay (unsigned long loops) ia64_delay_loop (loops - 1); } -static __inline__ void -udelay (unsigned long usecs) -{ - unsigned long start = ia64_get_itc(); - unsigned long cycles = usecs*local_cpu_data->cyc_per_usec; - - while (ia64_get_itc() - start < cycles) - cpu_relax(); -} +extern void udelay (unsigned long usecs); #endif /* _ASM_IA64_DELAY_H */ From 4d7672b46244abffea1953e55688c0ea143dd617 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Dec 2005 10:21:23 -0800 Subject: [PATCH 74/91] Make sure we copy pages inserted with "vm_insert_page()" on fork The logic that decides that a fork() might be able to avoid copying a VM area when it can be re-created by page faults didn't know about the new vm_insert_page() case. Also make some things a bit more anal wrt VM_PFNMAP. Pointed out by Hugh Dickins Signed-off-by: Linus Torvalds --- include/linux/mm.h | 1 + mm/memory.c | 3 ++- mm/mmap.c | 2 +- mm/mremap.c | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index e5677f456742..a06a84d347fb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -163,6 +163,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ +#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS diff --git a/mm/memory.c b/mm/memory.c index d22f78c8a381..d8dde07a3656 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -574,7 +574,7 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, * readonly mappings. The tradeoff is that copy_page_range is more * efficient than faulting. */ - if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP))) { + if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) { if (!vma->anon_vma) return 0; } @@ -1228,6 +1228,7 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page * return -EFAULT; if (!page_count(page)) return -EINVAL; + vma->vm_flags |= VM_INSERTPAGE; return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot); } EXPORT_SYMBOL(vm_insert_page); diff --git a/mm/mmap.c b/mm/mmap.c index 11ca5927d5ff..64ba4dbcb7de 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -611,7 +611,7 @@ again: remove_next = 1 + (end > next->vm_end); * If the vma has a ->close operation then the driver probably needs to release * per-vma resources, so we don't attempt to merge those. */ -#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED) +#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP) static inline int is_mergeable_vma(struct vm_area_struct *vma, struct file *file, unsigned long vm_flags) diff --git a/mm/mremap.c b/mm/mremap.c index b535438c363c..ddaeee9a0b69 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -323,7 +323,7 @@ unsigned long do_mremap(unsigned long addr, /* We can't remap across vm area boundaries */ if (old_len > vma->vm_end - addr) goto out; - if (vma->vm_flags & VM_DONTEXPAND) { + if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { if (new_len > old_len) goto out; } From 3bd7f01713f30e7c616ab975ebb84ab7eb58a60a Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 16 Dec 2005 11:00:03 -0500 Subject: [PATCH 75/91] [IA64] uncached ref count leak Use raw_smp_processor_id() instead of get_cpu() as we don't need the extra features of get_cpu(). Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck --- arch/ia64/kernel/uncached.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index c6d40446c2c4..b631cf86ed44 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -53,7 +53,7 @@ static void uncached_ipi_visibility(void *data) if ((status != PAL_VISIBILITY_OK) && (status != PAL_VISIBILITY_OK_REMOTE_NEEDED)) printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on " - "CPU %i\n", status, get_cpu()); + "CPU %i\n", status, raw_smp_processor_id()); } @@ -63,7 +63,7 @@ static void uncached_ipi_mc_drain(void *data) status = ia64_pal_mc_drain(); if (status) printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on " - "CPU %i\n", status, get_cpu()); + "CPU %i\n", status, raw_smp_processor_id()); } @@ -105,7 +105,7 @@ uncached_get_new_chunk(struct gen_pool *poolp) status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL); dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n", - status, get_cpu()); + status, raw_smp_processor_id()); if (!status) { status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1); From d74700e604db717eef7a3112176e6350fb00d0e3 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Thu, 15 Dec 2005 12:41:22 -0600 Subject: [PATCH 76/91] [IA64-SGI] Missed TLB flush I see why the problem exists only on SN. SN uses a different hardware mechanism to purge TLB entries across nodes. It looks like there is a bug in the SN TLB flushing code. During context switch, kernel threads inherit the mm of the task that was previously running on the cpu. This confuses the code in sn2_global_tlb_purge(). The result is a missed TLB purge for the task that owns the "borrowed" mm. (I hit the problem running heavy stress where kswapd was purging code pages of a user task that woke kswapd. The user task took a SIGILL fault trying to execute code in the page that had been ripped out from underneath it). Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/sn2_smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 5d54f5f4e926..471bbaa65d1b 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -202,7 +202,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) { int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; - int mymm = (mm == current->active_mm); + int mymm = (mm == current->active_mm && current->mm); volatile unsigned long *ptc0, *ptc1; unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; short nasids[MAX_NUMNODES], nix; From d5bf3165b6fbb879a4658f9da9ca2fe002b75f08 Mon Sep 17 00:00:00 2001 From: "hawkes@sgi.com" Date: Tue, 13 Dec 2005 13:45:44 -0800 Subject: [PATCH 77/91] [IA64-SGI] change default_sn2 to NR_CPUS==1024 Change the NR_CPUS default for ia64/sn up to 1024. Signed-off-by: John Hawkes Signed-off-by: John Hesterberg Signed-off-by: Tony Luck --- arch/ia64/configs/sn2_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index e1924cc9687b..ff8bb3770c9d 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -113,7 +113,7 @@ CONFIG_IOSAPIC=y CONFIG_IA64_SGI_SN_XP=m CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y -CONFIG_NR_CPUS=512 +CONFIG_NR_CPUS=1024 # CONFIG_HOTPLUG_CPU is not set CONFIG_SCHED_SMT=y CONFIG_PREEMPT=y From dc86e88c2bb8a7603ee175fbb6a9e92cf3293dd8 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 12 Dec 2005 09:34:32 -0800 Subject: [PATCH 78/91] [IA64] Add __read_mostly support for IA64 sparc64, i386 and x86_64 have support for a special data section dedicated to rarely updated data that is frequently read. The section was created to avoid false sharing of those rarely read data with frequently written kernel data. This patch creates such a data section for ia64 and will group rarely written data into this section. Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- arch/ia64/kernel/vmlinux.lds.S | 3 +++ include/linux/cache.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 30d8564e9603..73af6267d2ef 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -177,6 +177,9 @@ SECTIONS } . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) + { *(.data.read_mostly) } + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { *(.data.cacheline_aligned) } diff --git a/include/linux/cache.h b/include/linux/cache.h index f6b5a46c5f82..0b7ecf3af78a 100644 --- a/include/linux/cache.h +++ b/include/linux/cache.h @@ -13,7 +13,7 @@ #define SMP_CACHE_BYTES L1_CACHE_BYTES #endif -#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) +#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) #define __read_mostly __attribute__((__section__(".data.read_mostly"))) #else #define __read_mostly From dfded4ae71080b53798c7bbf4628a9b22d1e3e8b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Fri, 16 Dec 2005 11:08:43 -0800 Subject: [PATCH 79/91] [PATCH] i2c: Fix i2c-mv64xxx compilation error The busses/i2c-mv64xxx.c driver doesn't currently compile because of an incorrect argument to dev_err(). This patch fixes that. Signed-off-by: Mark A. Greer Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/i2c/busses/i2c-mv64xxx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index afd7634e5cc9..81031eb51056 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -529,14 +529,15 @@ mv64xxx_i2c_probe(struct platform_device *pd) i2c_set_adapdata(&drv_data->adapter, drv_data); if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, - MV64XXX_I2C_CTLR_NAME, drv_data)) { - - dev_err(dev, "mv64xxx: Can't register intr handler " - "irq: %d\n", drv_data->irq); + MV64XXX_I2C_CTLR_NAME, drv_data)) { + dev_err(&drv_data->adapter.dev, + "mv64xxx: Can't register intr handler irq: %d\n", + drv_data->irq); rc = -EINVAL; goto exit_unmap_regs; } else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) { - dev_err(dev, "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); + dev_err(&drv_data->adapter.dev, + "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); goto exit_free_irq; } From 52f975ea21e28871a371c2d941e13d64c9f8cd66 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 16 Dec 2005 11:08:48 -0800 Subject: [PATCH 80/91] [PATCH] PCI express must be initialized before PCI hotplug PCI express hotplug uses the pcieportbus driver so pcie must be initialized before hotplug/. This patch changes the link order. Signed-Off-By: Milton Miller Acked-by: Anton Blanchard Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/pci/Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 716df015f8d0..6707df968934 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -6,6 +6,9 @@ obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o obj-$(CONFIG_PROC_FS) += proc.o +# Build PCI Express stuff if needed +obj-$(CONFIG_PCIEPORTBUS) += pcie/ + obj-$(CONFIG_HOTPLUG) += hotplug.o # Build the PCI Hotplug drivers if we were asked to @@ -40,7 +43,3 @@ endif ifeq ($(CONFIG_PCI_DEBUG),y) EXTRA_CFLAGS += -DDEBUG endif - -# Build PCI Express stuff if needed -obj-$(CONFIG_PCIEPORTBUS) += pcie/ - From 42f3ab42875a52af7e711803bfb8d8d7cca84c1c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 16 Dec 2005 11:08:55 -0800 Subject: [PATCH 81/91] [PATCH] PCI: Fix dumb bug in mmconfig fix Use correct address when referencing mmconfig aperture while checking for broken MCFG. This was a typo when porting the code from 64bit to 32bit. It caused oopses at boot on some ThinkPads. Should definitely go into 2.6.15. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- arch/i386/pci/mmconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 70a9cc132cf7..4bb4d4b0f73a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -155,7 +155,7 @@ static __init void unreachable_devices(void) addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); if (addr != 0) pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); - if (addr == 0 || readl((u32 __iomem *)addr) != val1) + if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) set_bit(i, fallback_slots); spin_unlock_irqrestore(&pci_config_lock, flags); } From 42245e65f356ed54fdf7a1f9a0095e0bc40f73a3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 16 Dec 2005 11:09:01 -0800 Subject: [PATCH 82/91] [PATCH] UHCI: add missing memory barriers This patch (as617) adds a couple of memory barriers that Ben H. forgot in his recent suspend/resume fix. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/usb/host/uhci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index ed550132db0b..79efaf7d86a3 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -717,6 +717,7 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) * at the source, so we must turn off PIRQ. */ pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); + mb(); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); uhci->hc_inaccessible = 1; hcd->poll_rh = 0; @@ -738,6 +739,7 @@ static int uhci_resume(struct usb_hcd *hcd) * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0 */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + mb(); if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ return 0; From a78719c387cc25ed97304a235a20c24f0f89399b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 16 Dec 2005 22:35:28 +0000 Subject: [PATCH 83/91] [PATCH] ppc: booke_wdt compile fix booke_wdt.c had been missed in cpu_specs[] removal sweep Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/char/watchdog/booke_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c index c800cce73c1e..b6640606b44d 100644 --- a/drivers/char/watchdog/booke_wdt.c +++ b/drivers/char/watchdog/booke_wdt.c @@ -173,7 +173,7 @@ static int __init booke_wdt_init(void) int ret = 0; printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n"); - ident.firmware_version = cpu_specs[0].pvr_value; + ident.firmware_version = cur_cpu_spec->pvr_value; ret = misc_register(&booke_wdt_miscdev); if (ret) { From 7c3dbbe982ac85837f1da150ea9539a9e9a12557 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 16 Dec 2005 22:35:23 +0000 Subject: [PATCH 84/91] [PATCH] ppc: ppc4xx_dma DMA_MODE_{READ,WRITE} fix DMA_MODE_{READ,WRITE} are declared in asm-powerpc/dma.h and their declarations there match the definitions. Old declarations in ppc4xx_dma.h are not right anymore (wrong type, to start with). Killed them, added include of asm/dma.h where needed. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- arch/ppc/syslib/ppc4xx_dma.c | 1 + include/asm-ppc/ppc4xx_dma.h | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c index f15e64285f96..05ccd598dd4e 100644 --- a/arch/ppc/syslib/ppc4xx_dma.c +++ b/arch/ppc/syslib/ppc4xx_dma.c @@ -30,6 +30,7 @@ #include #include +#include #include ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS]; diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h index a415001165fa..46a086fff816 100644 --- a/include/asm-ppc/ppc4xx_dma.h +++ b/include/asm-ppc/ppc4xx_dma.h @@ -33,9 +33,6 @@ #define MAX_PPC4xx_DMA_CHANNELS 4 -/* in arch/ppc/kernel/setup.c -- Cort */ -extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ; - /* * Function return status codes * These values are used to indicate whether or not the function From 87d47d0547631e059c308b392cd2423fe9248c93 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Sat, 17 Dec 2005 18:39:23 -0800 Subject: [PATCH 85/91] [PATCH] i2o: Do not disable pci device when it's in use When dpt_i2o is loaded first, i2o being loaded would cause it to call pci_device_disable, thus breaking dpt_i2o's use of the device. Based on similar usage of pci_disable_device in other drivers. Signed-off-by: Ben Collins Signed-off-by: Linus Torvalds --- drivers/message/i2o/pci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 81ef306cb124..ee7075fa1ec3 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c @@ -303,6 +303,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, struct i2o_controller *c; int rc; struct pci_dev *i960 = NULL; + int pci_dev_busy = 0; printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); @@ -395,6 +396,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, if ((rc = i2o_pci_alloc(c))) { printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " " failed\n", c->name); + if (rc == -ENODEV) + pci_dev_busy = 1; goto free_controller; } @@ -425,7 +428,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, i2o_iop_free(c); disable: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } From e5508c13ac25b07585229b144a45cf64a990171e Mon Sep 17 00:00:00 2001 From: "Salyzyn, Mark" Date: Sat, 17 Dec 2005 19:26:30 -0800 Subject: [PATCH 86/91] [PATCH] dpt_i2o fix for deadlock condition Miquel van Smoorenburg forwarded me this fix to resolve a deadlock condition that occurs due to the API change in 2.6.13+ kernels dropping the host locking when entering the error handling. They all end up calling adpt_i2o_post_wait(), which if you call it unlocked, might return with host_lock locked anyway and that causes a deadlock. Signed-off-by: Mark Salyzyn Cc: James Bottomley Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/dpt_i2o.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 418fc7b896ac..6252b9ddc01e 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd * cmd) msg[2] = 0; msg[3]= 0; msg[4] = (u32)cmd; - if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){ + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); + rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { if(rcode == -EOPNOTSUPP ){ printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); return FAILED; @@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) msg[2] = 0; msg[3] = 0; + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); old_state = d->state; d->state |= DPTI_DEV_RESET; - if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){ - d->state = old_state; + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); + d->state = old_state; + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { if(rcode == -EOPNOTSUPP ){ printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); return FAILED; @@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) printk(KERN_INFO"%s: Device reset failed\n",pHba->name); return FAILED; } else { - d->state = old_state; printk(KERN_INFO"%s: Device reset successful\n",pHba->name); return SUCCESS; } @@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) { adpt_hba* pHba; u32 msg[4]; + u32 rcode; pHba = (adpt_hba*)cmd->device->host->hostdata[0]; memset(msg, 0, sizeof(msg)); @@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); msg[2] = 0; msg[3] = 0; - if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){ + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); return FAILED; } else { From 9ce7677cfd7cd871adb457c80bea3b581b839641 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 18 Dec 2005 17:50:32 +0100 Subject: [PATCH 87/91] [PATCH] uml: arch/um/scripts/Makefile.rules - remove duplicated code Duplicated code - the patch adding it was probably applied twice without enough care. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/scripts/Makefile.rules | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index b3fbf125709b..2e41cabd3d93 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -21,11 +21,6 @@ define unprofile endef -# The stubs and unmap.o can't try to call mcount or update basic block data -define unprofile - $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) -endef - # cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If # so, it's considered to be a path relative to $(srcdir) rather than # $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from From 53c0b59dcdb7c68c3cfd4b9a0bd17373b785f2eb Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 18 Dec 2005 17:50:35 +0100 Subject: [PATCH 88/91] [PATCH] uml: fix dynamic linking on some 64-bit distros With Paolo 'Blaisorblade' Giarrusso The current UML build assumes that on x86-64 systems, /lib is a symlink to /lib64, but in some distributions (like PLD and CentOS) they are separate directories, so the 64 bit library loader isn't found. This patch inserts /lib64 at the start of the rpath on x86-64 UML builds. Signed-off-by: Rob Landley Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/Makefile-x86_64 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index 4f118d5cc2ee..38df311e75dc 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -12,3 +12,7 @@ CHECKFLAGS += -m64 ELF_ARCH := i386:x86-64 ELF_FORMAT := elf64-x86-64 + +# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. + +LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 From 76c842d8f8096e2c98ff9ebe1db861363ff254e5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 18 Dec 2005 17:50:37 +0100 Subject: [PATCH 89/91] [PATCH] uml - fix some funkiness in Kconfig So you may have seen the miniconfig stuff wander by, which means that my build script exits if there's a .config error, and we have this: fs/Kconfig:1749:warning: 'select' used by config symbol 'CIFS_UPCALL' refer to undefined symbol 'CONNECTOR' This makes it shut up. Signed-off-by: Rob Landley [ Verified it makes sense. ] Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 563301fe5df8..1eb21de9d1b5 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -289,6 +289,8 @@ source "arch/um/Kconfig.net" source "drivers/net/Kconfig" +source "drivers/connector/Kconfig" + source "fs/Kconfig" source "security/Kconfig" From 5b7b15afee89d6940482259b54d0864b7b2302b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 18 Dec 2005 17:50:39 +0100 Subject: [PATCH 90/91] [PATCH] uml skas0: stop gcc's insanity With Paolo 'Blaisorblade' Giarrusso UML skas0 stub has been miscompiling for many people (incidentally not the authors), depending on the used GCC versions. I think (and testing on some GCC versions shows) this patch avoids the fundamental issue which is behind this, namely gcc using the stack when we have just replaced it, behind gcc's back. The remapping and storage of the return value is hidden in a blob of asm, hopefully giving gcc no room for creativity. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/stub.h | 31 +++++++++++++++------------ arch/um/include/sysdep-x86_64/stub.h | 32 ++++++++++++++++------------ arch/um/kernel/skas/clone.c | 23 +++++++++++--------- 3 files changed, 48 insertions(+), 38 deletions(-) diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index 6ba8cbbe0d36..b492b12b4a10 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h @@ -6,8 +6,12 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H +#include #include #include +#include "stub-data.h" +#include "kern_constants.h" +#include "uml-config.h" extern void stub_segv_handler(int sig); extern void stub_clone_handler(void); @@ -76,23 +80,22 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, return ret; } -static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6) -{ - long ret; - - __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; " - "int $0x80 ; pop %%ebp" - : "=a" (ret) - : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3), - "S" (arg4), "D" (arg5), "0" (arg6)); - - return ret; -} - static inline void trap_myself(void) { __asm("int3"); } +static inline void remap_stack(int fd, unsigned long offset) +{ + __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" + "movl %7, %%ebx ; movl %%eax, (%%ebx)" + : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), + "c" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "S" (MAP_FIXED | MAP_SHARED), "D" (fd), + "a" (offset), + "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + : "memory"); +} + #endif diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h index c41689c13dc9..92e989f81761 100644 --- a/arch/um/include/sysdep-x86_64/stub.h +++ b/arch/um/include/sysdep-x86_64/stub.h @@ -6,8 +6,12 @@ #ifndef __SYSDEP_STUB_H #define __SYSDEP_STUB_H +#include #include #include +#include "stub-data.h" +#include "kern_constants.h" +#include "uml-config.h" extern void stub_segv_handler(int sig); extern void stub_clone_handler(void); @@ -81,23 +85,23 @@ static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, return ret; } -static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6) -{ - long ret; - - __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " - "movq %7, %%r9; " __syscall : "=a" (ret) - : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), - "g" (arg4), "g" (arg5), "g" (arg6) - : __syscall_clobber, "r10", "r8", "r9" ); - - return ret; -} - static inline void trap_myself(void) { __asm("int3"); } +static inline void remap_stack(long fd, unsigned long offset) +{ + __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " + "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " + "movq %%rax, (%%rbx)": + : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), + "S" (UM_KERN_PAGE_SIZE), + "d" (PROT_READ | PROT_WRITE), + "g" (MAP_FIXED | MAP_SHARED), "g" (fd), + "g" (offset), + "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) + : __syscall_clobber, "r10", "r8", "r9" ); +} + #endif diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index cb37ce9124a6..47b812b3bca8 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -18,11 +18,10 @@ * on some systems. */ -#define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field) - void __attribute__ ((__section__ (".__syscall_stub"))) stub_clone_handler(void) { + struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; long err; err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, @@ -35,17 +34,21 @@ stub_clone_handler(void) if(err) goto out; - err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, - (long) &STUB_DATA(timer), 0); + err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, + (long) &data->timer, 0); if(err) goto out; - err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, - UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, STUB_DATA(fd), - STUB_DATA(offset)); + remap_stack(data->fd, data->offset); + goto done; + out: - /* save current result. Parent: pid; child: retcode of mmap */ - STUB_DATA(err) = err; + /* save current result. + * Parent: pid; + * child: retcode of mmap already saved and it jumps around this + * assignment + */ + data->err = err; + done: trap_myself(); } From ff60dde9e46b87757d5e83bd58be0688fca8e816 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 17 Dec 2005 11:42:54 -0500 Subject: [PATCH 91/91] [PATCH] Input: fix an OOPS in HID driver This patch fixes an OOPS in HID driver when connecting simulation devices generating unknown simulation events. Signed-off-by: Dmitry Torokhov Acked-by: Vojtech Pavlik Signed-off-by: Linus Torvalds --- drivers/usb/input/hid-input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9ff25eb520a6..1220a5004a5c 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c @@ -137,6 +137,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel switch (usage->hid & 0xffff) { case 0xba: map_abs(ABS_RUDDER); break; case 0xbb: map_abs(ABS_THROTTLE); break; + default: goto ignore; } break;