From bb58596f6802a4959c2cea02acd272245e671c1d Mon Sep 17 00:00:00 2001 From: Dave C Boutcher Date: Tue, 15 Nov 2005 09:53:00 -0600 Subject: [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; } -- cgit v1.2.3 From 23443b1d6130eff8e1335e4f84eaf0577a331dcf Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 6 Dec 2005 10:57:06 -0800 Subject: [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) { -- cgit v1.2.3 From 0da69df1e54146eece38e0a144051f6dd3526821 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 6 Dec 2005 10:58:06 -0800 Subject: [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; -- cgit v1.2.3 From f0353301e6752399ceb874ede7f44e3571c5e4f3 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 7 Dec 2005 17:46:57 -0500 Subject: [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; -- cgit v1.2.3 From 85631672e6a8032267058b4ccbe53f1924a5d0be Mon Sep 17 00:00:00 2001 From: Michael Reed Date: Wed, 7 Dec 2005 21:46:27 -0600 Subject: [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); } /** -- cgit v1.2.3 From a8c730e85e80734412f4f73ab28496a0e8b04a7b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 9 Dec 2005 14:42:16 +0100 Subject: [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 | 8 ++++---- 1 file changed, 4 insertions(+), 4 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) + 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 if (req->data_len) - cmd->sc_data_direction = DMA_FROM_DEVICE; else - cmd->sc_data_direction = DMA_NONE; + cmd->sc_data_direction = DMA_FROM_DEVICE; cmd->transfersize = req->data_len; cmd->allowed = 3; -- cgit v1.2.3 From 1ee9530a71686436dbeb5f31dd5b925c39cf71d7 Mon Sep 17 00:00:00 2001 From: Lothar Wassmann Date: Mon, 12 Dec 2005 16:44:05 +0000 Subject: [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 -- cgit v1.2.3 From 1a68de5c08be8c77c4ad208306187bd95107c7cd Mon Sep 17 00:00:00 2001 From: Brian King Date: Mon, 12 Dec 2005 13:05:08 -0600 Subject: [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) -- cgit v1.2.3 From dfa159886f38344ede31e3b13ec614e0bebc09c6 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Mon, 12 Dec 2005 23:19:28 -0500 Subject: [PATCH] libata-core.c: fix parameter bug on kunmap_atomic() calls Fix incorrect pointer usage on two calls to kunmap_atomic(). This seems to happen a lot, because kunmap() wants the struct page *, whereas kunmap_atomic() instead wants the mapped virtual address. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/libata-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 665ae79e1fd6..d0a0fdbd0fc4 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2443,7 +2443,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) struct scatterlist *psg = &qc->pad_sgent; void *addr = kmap_atomic(psg->page, KM_IRQ0); memcpy(addr + psg->offset, pad_buf, qc->pad_len); - kunmap_atomic(psg->page, KM_IRQ0); + kunmap_atomic(addr, KM_IRQ0); } } else { if (sg_dma_len(&sg[0]) > 0) @@ -2717,7 +2717,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_WRITE) { void *addr = kmap_atomic(psg->page, KM_IRQ0); memcpy(pad_buf, addr + psg->offset, qc->pad_len); - kunmap_atomic(psg->page, KM_IRQ0); + kunmap_atomic(addr, KM_IRQ0); } sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); -- cgit v1.2.3 From ee1c81917a0c10f44c1b400482b8372e68238ff8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2005 15:01:49 -0800 Subject: [PATCH] skge: get rid of warning on race Get rid of warning in case of race with ring full and lockless tx on the skge driver. It is possible to be in the transmit routine with no available slots and already stopped. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/skge.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 716467879b9c..8b6e2a11e28d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2280,11 +2280,13 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) } if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { - netif_stop_queue(dev); - spin_unlock_irqrestore(&skge->tx_lock, flags); + if (!netif_stopped(dev)) { + netif_stop_queue(dev); - printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", - dev->name); + printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", + dev->name); + } + spin_unlock_irqrestore(&skge->tx_lock, flags); return NETDEV_TX_BUSY; } -- cgit v1.2.3 From 1cf9e8a7865c0ac216034e519cf6b8505055ea50 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 1 Dec 2005 21:22:37 +0100 Subject: [PATCH] ieee80211_crypt_tkip depends on NET_RADIO *** Warning: ".wireless_send_event" [net/ieee80211/ieee80211_crypt_tkip.ko] undefined! Signed-off-by: Olaf Hering net/ieee80211/Kconfig | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Jeff Garzik --- net/ieee80211/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig index 91b16fbf91f0..d18ccba3ea9e 100644 --- a/net/ieee80211/Kconfig +++ b/net/ieee80211/Kconfig @@ -55,7 +55,7 @@ config IEEE80211_CRYPT_CCMP config IEEE80211_CRYPT_TKIP tristate "IEEE 802.11i TKIP encryption" - depends on IEEE80211 + depends on IEEE80211 && NET_RADIO select CRYPTO select CRYPTO_MICHAEL_MIC ---help--- -- cgit v1.2.3 From 47807ce381acc34a7ffee2b42e35e96c0f322e52 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 13 Dec 2005 04:18:41 +0000 Subject: [drm] fix radeon aperture issue Ben noticed that on certain cards we've landed the AGP space on top of the second aperture instead of after it.. Which messes things up a lot on those machines. This just moves the gart further out, a more correct fix is in the works from Ben for after 2.6.15. Signed-off-by: Dave Airlie CC: Ben Herrenschmidt Signed-off-by: Linus Torvalds --- drivers/char/drm/radeon_cp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 03839ea31092..9f2b4efd0c7a 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -1522,7 +1522,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->gart_size = init->gart_size; dev_priv->gart_vm_start = dev_priv->fb_location - + RADEON_READ(RADEON_CONFIG_APER_SIZE); + + RADEON_READ(RADEON_CONFIG_APER_SIZE) * 2; #if __OS_HAS_AGP if (!dev_priv->is_pci) -- cgit v1.2.3 From 68e188911263adb06e28fa2c9dc9e017774de68d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Dec 2005 22:17:07 -0800 Subject: [PATCH] x86_64: Make sure hpet_address is 0 when any part of HPET initialization fails Otherwise TSC->HPET fallback could see incorrect state and crash later. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/time.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index fdaddc4e5284..4434e154f596 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -59,7 +59,7 @@ static int notsc __initdata = 0; unsigned int cpu_khz; /* TSC clocks / usec, not used here */ static unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* HPET clocks / interrupt */ -static int hpet_use_timer; +static int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ unsigned long vxtime_hz = PIT_TICK_RATE; int report_lost_ticks; /* command line option */ unsigned long long monotonic_base; @@ -908,6 +908,8 @@ void __init time_init(void) if (!hpet_init()) vxtime_hz = (1000000000000000L + hpet_period / 2) / hpet_period; + else + vxtime.hpet_address = 0; if (hpet_use_timer) { cpu_khz = hpet_calibrate_tsc(); -- cgit v1.2.3 From 5e9ef02ec00c70840661d174dc2f4862db471bb6 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 12 Dec 2005 22:17:08 -0800 Subject: [PATCH] i386/x86-64 disable LAPIC completely for offline CPU Disabling LAPIC timer isn't sufficient. In some situations, such as we enabled NMI watchdog, there is still unexpected interrupt (such as NMI) invoked in offline CPU. This also avoids offline CPU receives spurious interrupt and anything similar. Signed-off-by: Shaohua Li Signed-off-by: Andi Kleen Acked-by: "Seth, Rohit" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/smpboot.c | 3 +-- arch/x86_64/kernel/smpboot.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index d16520da4550..9ed449af8e9f 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1338,8 +1338,7 @@ int __cpu_disable(void) if (cpu == 0) return -EBUSY; - /* We enable the timer again on the exit path of the death loop */ - disable_APIC_timer(); + clear_local_APIC(); /* Allow any queued timer interrupts to get serviced */ local_irq_enable(); mdelay(1); diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 683c33f7b967..ecbd7b83acc1 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -1181,7 +1181,7 @@ int __cpu_disable(void) if (cpu == 0) return -EBUSY; - disable_APIC_timer(); + clear_local_APIC(); /* * HACK: -- cgit v1.2.3 From bf5421c309bb89e5106452bc840983b1b4754d61 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Dec 2005 22:17:09 -0800 Subject: [PATCH] i386/x86-64: Don't call change_page_attr with a spinlock held It's illegal because it can sleep. Use a two step lookup scheme instead. First look up the vm_struct, then change the direct mapping, then finally unmap it. That's ok because nobody can change the particular virtual address range as long as the vm_struct is still in the global list. Also added some LinuxDoc documentation to iounmap. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/ioremap.c | 37 +++++++++++++++++++++++++++++-------- arch/x86_64/mm/ioremap.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 5d09de8d1c6b..8498b5ac3955 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -223,9 +223,15 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) } EXPORT_SYMBOL(ioremap_nocache); +/** + * iounmap - Free a IO remapping + * @addr: virtual address from ioremap_* + * + * Caller must ensure there is only one unmapping for the same pointer. + */ void iounmap(volatile void __iomem *addr) { - struct vm_struct *p; + struct vm_struct *p, *o; if ((void __force *)addr <= high_memory) return; @@ -239,22 +245,37 @@ void iounmap(volatile void __iomem *addr) addr < phys_to_virt(ISA_END_ADDRESS)) return; - write_lock(&vmlist_lock); - p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); - if (!p) { - printk(KERN_WARNING "iounmap: bad address %p\n", addr); + addr = (volatile void *)(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 + leaving it in the global lists until we're done with it. + cpa takes care of the direct mappings. */ + read_lock(&vmlist_lock); + for (p = vmlist; p; p = p->next) { + if (p->addr == addr) + break; + } + read_unlock(&vmlist_lock); + + if (!p) { + printk("iounmap: bad address %p\n", addr); dump_stack(); - goto out_unlock; + return; } + /* Reset the direct mapping. Can block */ if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { change_page_attr(virt_to_page(__va(p->phys_addr)), p->size >> PAGE_SHIFT, PAGE_KERNEL); global_flush_tlb(); } -out_unlock: - write_unlock(&vmlist_lock); + + /* Finally remove it */ + o = remove_vm_area((void *)addr); + BUG_ON(p != o || o == NULL); kfree(p); } EXPORT_SYMBOL(iounmap); diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index ecf7acb5db9b..0d260e4492f7 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c @@ -247,9 +247,15 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) return __ioremap(phys_addr, size, _PAGE_PCD); } +/** + * iounmap - Free a IO remapping + * @addr: virtual address from ioremap_* + * + * Caller must ensure there is only one unmapping for the same pointer. + */ void iounmap(volatile void __iomem *addr) { - struct vm_struct *p; + struct vm_struct *p, *o; if (addr <= high_memory) return; @@ -257,12 +263,31 @@ void iounmap(volatile void __iomem *addr) addr < phys_to_virt(ISA_END_ADDRESS)) return; - write_lock(&vmlist_lock); - p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK)); - if (!p) + addr = (volatile void *)(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 + leaving it in the global lists until we're done with it. + cpa takes care of the direct mappings. */ + read_lock(&vmlist_lock); + for (p = vmlist; p; p = p->next) { + if (p->addr == addr) + break; + } + read_unlock(&vmlist_lock); + + if (!p) { printk("iounmap: bad address %p\n", addr); - else if (p->flags >> 20) + dump_stack(); + return; + } + + /* Reset the direct mapping. Can block */ + if (p->flags >> 20) ioremap_change_attr(p->phys_addr, p->size, 0); - write_unlock(&vmlist_lock); + + /* Finally remove it */ + o = remove_vm_area((void *)addr); + BUG_ON(p != o || o == NULL); kfree(p); } -- cgit v1.2.3 From 928cf8c62763349efc550a12f6518e52c3390906 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Dec 2005 22:17:10 -0800 Subject: [PATCH] i386/x86-64 Fall back to type 1 access when no entry found When there is no entry for a bus in MCFG fall back to type1. This is especially important on K8 systems where always some devices can't be accessed using mmconfig (in particular the builtin northbridge doesn't support it for its own devices) Cc: Cc: Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/pci/direct.c | 4 ++-- arch/i386/pci/mmconfig.c | 24 ++++++++++++++++-------- arch/i386/pci/pci.h | 7 +++++++ arch/x86_64/pci/mmconfig.c | 29 ++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c index 94331d6be7a3..e3ac502bf2fb 100644 --- a/arch/i386/pci/direct.c +++ b/arch/i386/pci/direct.c @@ -13,7 +13,7 @@ #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) -static int pci_conf1_read(unsigned int seg, unsigned int bus, +int pci_conf1_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { unsigned long flags; @@ -42,7 +42,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, return 0; } -static int pci_conf1_write(unsigned int seg, unsigned int bus, +int pci_conf1_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { unsigned long flags; diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index dfbf80cff834..cc787a7c030c 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -30,10 +30,8 @@ static u32 get_base_addr(unsigned int seg, int bus) while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) { - /* something bad is going on, no cfg table is found. */ - /* so we fall back to the old way we used to do this */ - /* and just rely on the first entry to be correct. */ - return pci_mmcfg_config[0].base_address; + /* Not found - fallback to type 1 */ + return 0; } cfg = &pci_mmcfg_config[cfg_num]; if (cfg->pci_segment_group_number != seg) @@ -44,9 +42,9 @@ static u32 get_base_addr(unsigned int seg, int bus) } } -static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) { - u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); + u32 dev_base = base | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -57,13 +55,18 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { unsigned long flags; + u32 base; if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; + base = get_base_addr(seg, bus); + if (!base) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(seg, bus, devfn); + pci_exp_set_dev_base(base, bus, devfn); switch (len) { case 1: @@ -86,13 +89,18 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { unsigned long flags; + u32 base; if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; + base = get_base_addr(seg, bus); + if (!base) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(seg, bus, devfn); + pci_exp_set_dev_base(base, bus, devfn); switch (len) { case 1: diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 127d53ad16be..f550781ec310 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -74,3 +74,10 @@ extern spinlock_t pci_config_lock; extern int (*pcibios_enable_irq)(struct pci_dev *dev); extern void (*pcibios_disable_irq)(struct pci_dev *dev); + +extern int pci_conf1_write(unsigned int seg, unsigned int bus, + unsigned int devfn, int reg, int len, u32 value); +extern int pci_conf1_read(unsigned int seg, unsigned int bus, + unsigned int devfn, int reg, int len, u32 *value); + + diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index a0838c4a94e4..22ff1b07d4e0 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -19,7 +19,7 @@ struct mmcfg_virt { }; static struct mmcfg_virt *pci_mmcfg_virt; -static char *get_virt(unsigned int seg, int bus) +static char *get_virt(unsigned int seg, unsigned bus) { int cfg_num = -1; struct acpi_table_mcfg_config *cfg; @@ -27,10 +27,9 @@ static char *get_virt(unsigned int seg, int bus) while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) { - /* something bad is going on, no cfg table is found. */ - /* so we fall back to the old way we used to do this */ - /* and just rely on the first entry to be correct. */ - return pci_mmcfg_virt[0].virt; + /* Not found - fall back to type 1. This happens + e.g. on the internal devices of a K8 northbridge. */ + return NULL; } cfg = pci_mmcfg_virt[cfg_num].cfg; if (cfg->pci_segment_group_number != seg) @@ -43,18 +42,25 @@ static char *get_virt(unsigned int seg, int bus) static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { - - return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); + char *addr = get_virt(seg, bus); + if (!addr) + return NULL; + return addr + ((bus << 20) | (devfn << 12)); } static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr = pci_dev_base(seg, bus, devfn); + char *addr; + /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + addr = pci_dev_base(seg, bus, devfn); + if (!addr) + return pci_conf1_read(seg,bus,devfn,reg,len,value); + switch (len) { case 1: *value = readb(addr + reg); @@ -73,11 +79,16 @@ 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 = pci_dev_base(seg, bus, devfn); + char *addr; + /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; + addr = pci_dev_base(seg, bus, devfn); + if (!addr) + return pci_conf1_write(seg,bus,devfn,reg,len,value); + switch (len) { case 1: writeb(value, addr + reg); -- cgit v1.2.3 From d6ece5491ae71ded1237f59def88bcd1b19b6f60 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Dec 2005 22:17:11 -0800 Subject: [PATCH] i386/x86-64 Correct for broken MCFG tables on K8 systems They report all busses as MMCONFIG capable, but it never works for the internal devices in the CPU's builtin northbridge. It just probes all func 0 devices on bus 0 (the internal northbridge is currently always on bus 0) and if they are not accessible using MCFG they are put into a special fallback bitmap. On systems where it isn't we assume the BIOS vendor supplied correct MCFG. Requires the earlier patch for mmconfig type1 fallback Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/pci/mmconfig.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- arch/x86_64/pci/mmconfig.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index cc787a7c030c..08a084901212 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -19,14 +19,20 @@ /* The base address of the last MMCONFIG device accessed */ static u32 mmcfg_last_accessed_device; +static DECLARE_BITMAP(fallback_slots, 32); + /* * Functions for accessing PCI configuration space with MMCONFIG accesses */ -static u32 get_base_addr(unsigned int seg, int bus) +static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) { int cfg_num = -1; struct acpi_table_mcfg_config *cfg; + if (seg == 0 && bus == 0 && + test_bit(PCI_SLOT(devfn), fallback_slots)) + return 0; + while (1) { ++cfg_num; if (cfg_num >= pci_mmcfg_config_num) { @@ -60,7 +66,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; - base = get_base_addr(seg, bus); + base = get_base_addr(seg, bus, devfn); if (!base) return pci_conf1_read(seg,bus,devfn,reg,len,value); @@ -94,7 +100,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, if ((bus > 255) || (devfn > 255) || (reg > 4095)) return -EINVAL; - base = get_base_addr(seg, bus); + base = get_base_addr(seg, bus, devfn); if (!base) return pci_conf1_write(seg,bus,devfn,reg,len,value); @@ -124,6 +130,37 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; +/* K8 systems have some devices (typically in the builtin northbridge) + that are only accessible using type1 + Normally this can be expressed in the MCFG by not listing them + and assigning suitable _SEGs, but this isn't implemented in some BIOS. + Instead try to discover all devices on bus 0 that are unreachable using MM + and fallback for them. + We only do this for bus 0/seg 0 */ +static __init void unreachable_devices(void) +{ + int i; + unsigned long flags; + + for (i = 0; i < 32; i++) { + u32 val1; + u32 addr; + + pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1); + if (val1 == 0xffffffff) + continue; + + /* Locking probably not needed, but safer */ + spin_lock_irqsave(&pci_config_lock, flags); + 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) + set_bit(i, fallback_slots); + spin_unlock_irqrestore(&pci_config_lock, flags); + } +} + static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) @@ -139,6 +176,8 @@ static int __init pci_mmcfg_init(void) raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + unreachable_devices(); + out: return 0; } diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 22ff1b07d4e0..9c4f907e301c 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -8,10 +8,13 @@ #include #include #include +#include #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) +static DECLARE_BITMAP(fallback_slots, 32); + /* Static virtual mapping of the MMCONFIG aperture */ struct mmcfg_virt { struct acpi_table_mcfg_config *cfg; @@ -40,9 +43,12 @@ static char *get_virt(unsigned int seg, unsigned bus) } } -static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +static char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) { - char *addr = get_virt(seg, bus); + char *addr; + if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots)) + return NULL; + addr = get_virt(seg, bus); if (!addr) return NULL; return addr + ((bus << 20) | (devfn << 12)); @@ -109,6 +115,30 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; +/* K8 systems have some devices (typically in the builtin northbridge) + that are only accessible using type1 + Normally this can be expressed in the MCFG by not listing them + and assigning suitable _SEGs, but this isn't implemented in some BIOS. + Instead try to discover all devices on bus 0 that are unreachable using MM + and fallback for them. + We only do this for bus 0/seg 0 */ +static __init void unreachable_devices(void) +{ + int i; + for (i = 0; i < 32; i++) { + u32 val1; + char *addr; + + pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1); + if (val1 == 0xffffffff) + continue; + addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0)); + if (addr == NULL|| readl(addr) != val1) { + set_bit(i, &fallback_slots); + } + } +} + static int __init pci_mmcfg_init(void) { int i; @@ -139,6 +169,8 @@ static int __init pci_mmcfg_init(void) printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); } + unreachable_devices(); + raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; -- cgit v1.2.3 From df818a52fb5e64c72b21029fb9ba80583106932c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Dec 2005 22:17:12 -0800 Subject: [PATCH] x86_64: Fix 32bit thread coredumps When a register set is passed in don't try to fix up the pointer. Noticed by Al Viro Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/ia32/ia32_binfmt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 830feb272eca..2b760d0d9ce2 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -217,8 +217,7 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr if (!tsk_used_math(tsk)) return 0; if (!regs) - regs = (struct pt_regs *)tsk->thread.rsp0; - --regs; + regs = ((struct pt_regs *)tsk->thread.rsp0) - 1; if (tsk == current) unlazy_fpu(tsk); set_fs(KERNEL_DS); -- cgit v1.2.3 From fd4954714e8e7db9f6eb5878fa6111c46445ca81 Mon Sep 17 00:00:00 2001 From: john stultz Date: Mon, 12 Dec 2005 22:17:13 -0800 Subject: [PATCH] x86_64: Fix collision between pmtimer and pit/hpet On systems that do not support the HPET legacy functions (basically the IBM x460, but there could be others), in time_init() we accidentally fall into a PM timer conditional and set the vxtime_hz value to the PM timer's frequency. We then use this value with the HPET for timekeeping. This patch (which mimics the behavior in time_init_gtod) corrects the collision. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 4434e154f596..74102796e5c0 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -915,7 +915,7 @@ void __init time_init(void) cpu_khz = hpet_calibrate_tsc(); timename = "HPET"; #ifdef CONFIG_X86_PM_TIMER - } else if (pmtmr_ioport) { + } else if (pmtmr_ioport && !vxtime.hpet_address) { vxtime_hz = PM_TIMER_FREQUENCY; timename = "PM"; pit_init(); -- cgit v1.2.3 From 8309cf66fd90ccba9894adde2f3a8d7e1507e4d2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 12 Dec 2005 22:17:14 -0800 Subject: [PATCH] x86_64: Bug correction in populate_memnodemap() As reported by Keith Mannthey, there are problems in populate_memnodemap() The bug was that the compute_hash_shift() was returning 31, with incorrect initialization of memnodemap[] To correct the bug, we must use (1UL << shift) instead of (1 << shift) to avoid an integer overflow, and we must check that shift < 64 to avoid an infinite loop. Signed-off-by: Eric Dumazet Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/mm/numa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index a828a01739cc..15b67d2760cb 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c @@ -53,6 +53,8 @@ static int __init populate_memnodemap( int res = -1; unsigned long addr, end; + if (shift >= 64) + return -1; memset(memnodemap, 0xff, sizeof(memnodemap)); for (i = 0; i < numnodes; i++) { addr = nodes[i].start; @@ -65,7 +67,7 @@ static int __init populate_memnodemap( if (memnodemap[addr >> shift] != 0xff) return -1; memnodemap[addr >> shift] = i; - addr += (1 << shift); + addr += (1UL << shift); } while (addr < end); res = 1; } -- cgit v1.2.3 From 2f6331faf58a4727a9f1138cd6db30d05b124220 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Mon, 12 Dec 2005 22:17:14 -0800 Subject: [PATCH] cciss: fix for deregister_disk This patch adds setting our drv->queue = NULL back in deregister_disk. The drv->queue is part of our controller struct. blk_cleanup_queue works only on the queue in the gendisk struct. Signed-off-by: Mike Miller Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/cciss.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e34104d32637..c3441b3f086e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1464,8 +1464,10 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, request_queue_t *q = disk->queue; if (disk->flags & GENHD_FL_UP) del_gendisk(disk); - if (q) + if (q) { blk_cleanup_queue(q); + drv->queue = NULL; + } } } -- cgit v1.2.3 From 56f0d64de80733bda54d1cfa7ac0c736ab2de33b Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:15 -0800 Subject: [PATCH] fbcon: fix complement_mask() with 512 character map There is a bug in the complement_mask when you have a 512-character map. Linux boots to a default 256-character map and most probably your login profile is loading a 512-character map which results in a bad gpm cursor. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index bcea87c3cc06..c024ffd0266d 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2048,7 +2048,7 @@ static int fbcon_switch(struct vc_data *vc) struct fbcon_ops *ops; struct display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var; - int i, prev_console; + int i, prev_console, charcnt = 256; info = registered_fb[con2fb_map[vc->vc_num]]; ops = info->fbcon_par; @@ -2120,6 +2120,13 @@ static int fbcon_switch(struct vc_data *vc) vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; + + if (p->userfont) + charcnt = FNTCHARCNT(vc->vc_font.data); + + if (charcnt > 256) + vc->vc_complement_mask <<= 1; + updatescrollmode(p, info, vc); switch (p->scrollmode) { -- cgit v1.2.3 From 4743484718e1d710321f24f8ef7d0124a48291b3 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:16 -0800 Subject: [PATCH] fbcon: Add ability to save/restore graphics state Add hooks to save and restore the graphics state. These hooks are called in fbcon_blank() when entering/leaving KD_GRAPHICS mode. This is needed by savagefb at least so it can cooperate with savage_dri and by cyblafb. State save/restoration can be full or partial. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 5 ++++- include/linux/fb.h | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index c024ffd0266d..bd4500a8992e 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2191,11 +2191,14 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) ops->graphics = 1; if (!blank) { + if (info->fbops->fb_save_state) + info->fbops->fb_save_state(info); var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; fb_set_var(info, &var); ops->graphics = 0; ops->var = info->var; - } + } else if (info->fbops->fb_restore_state) + info->fbops->fb_restore_state(info); } if (!fbcon_is_inactive(vc, info)) { diff --git a/include/linux/fb.h b/include/linux/fb.h index 04a58f33ec53..55ccaf3706c1 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -617,6 +617,12 @@ struct fb_ops { /* perform fb specific mmap */ int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma); + + /* save current hardware state */ + void (*fb_save_state)(struct fb_info *info); + + /* restore saved state */ + void (*fb_restore_state)(struct fb_info *info); }; #ifdef CONFIG_FB_TILEBLITTING -- cgit v1.2.3 From 1207069f6f8f3d1b71641fdaa6cc04fca6fff9f5 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:17 -0800 Subject: [PATCH] fbdev: Pan display fixes - Fix fb_pan_display rejecting yoffsets that are valid if panning mode is ywrap. - Add more robust error checking in fb_pan_display specially since this function is accessible by userland apps. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6240aedb4154..10dfdf035264 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -722,14 +722,30 @@ static void try_to_load(int fb) int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) { + struct fb_fix_screeninfo *fix = &info->fix; int xoffset = var->xoffset; int yoffset = var->yoffset; - int err; + int err = 0, yres = info->var.yres; + + if (var->yoffset > 0) { + if (var->vmode & FB_VMODE_YWRAP) { + if (!fix->ywrapstep || (var->yoffset % fix->ywrapstep)) + err = -EINVAL; + else + yres = 0; + } else if (!fix->ypanstep || (var->yoffset % fix->ypanstep)) + err = -EINVAL; + } + + if (var->xoffset > 0 && (!fix->xpanstep || + (var->xoffset % fix->xpanstep))) + err = -EINVAL; + + if (err || !info->fbops->fb_pan_display || xoffset < 0 || + yoffset < 0 || var->yoffset + yres > info->var.yres_virtual || + var->xoffset + info->var.xres > info->var.xres_virtual) + return -EINVAL; - if (xoffset < 0 || yoffset < 0 || !info->fbops->fb_pan_display || - xoffset + info->var.xres > info->var.xres_virtual || - yoffset + info->var.yres > info->var.yres_virtual) - return -EINVAL; if ((err = info->fbops->fb_pan_display(var, info))) return err; info->var.xoffset = var->xoffset; -- cgit v1.2.3 From 4e1567d3aad9bae0ecc5bb047179cd026bfb035c Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:18 -0800 Subject: [PATCH] fbcon: Avoid illegal display panning Avoid calls to fb_pan_display when driver is suspended or not in text mode. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index bd4500a8992e..8068d2f7efe6 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2146,8 +2146,12 @@ static int fbcon_switch(struct vc_data *vc) scrollback_max = 0; scrollback_current = 0; - ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; - ops->update_start(info); + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); + } + fbcon_set_palette(vc, color_table); fbcon_clear_margins(vc, 0); @@ -2746,8 +2750,12 @@ static void fbcon_modechanged(struct fb_info *info) updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; - ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; - ops->update_start(info); + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; + ops->update_start(info); + } + fbcon_set_palette(vc, color_table); update_screen(vc); if (softback_buf) @@ -2784,8 +2792,13 @@ static void fbcon_set_all_vcs(struct fb_info *info) updatescrollmode(p, info, vc); scrollback_max = 0; scrollback_current = 0; - ops->var.xoffset = ops->var.yoffset = p->yscroll = 0; - ops->update_start(info); + + if (!fbcon_is_inactive(vc, info)) { + ops->var.xoffset = ops->var.yoffset = + p->yscroll = 0; + ops->update_start(info); + } + fbcon_set_palette(vc, color_table); update_screen(vc); if (softback_buf) -- cgit v1.2.3 From 39942fd8ff57c8623451bbfaffe8a184cc8b463a Mon Sep 17 00:00:00 2001 From: Knut Petersen Date: Mon, 12 Dec 2005 22:17:19 -0800 Subject: [PATCH] fbdev: fix switch to KD_TEXT, enhanced version Every framebuffer driver relies on the assumption that the set_par() function of the driver is called before drawing functions and other functions dependent on the hardware state are executed. Whenever you switch from X to a framebuffer console for the very first time, there is a chance that a broken X system has _not_ set the mode to KD_GRAPHICS, thus the vt and framebuffer code executes a screen redraw and several other functions before a set_par() is executed. This is believed to be not a bug of linux but a bug of X/xdm. At least some X releases used by SuSE and Debian show this behaviour. There was a 2nd case, but that has been fixed by Antonino Daplas on 10-dec-2005. This patch allows drivers to set a flag to inform fbcon_switch() that they prefer a set_par() call on every console switch, working around the problems caused by the broken X releases. The flag will be used by the next release of cyblafb and might help other drivers that assume a hardware state different to the one used by X. As the default behaviour does not change, this patch should be acceptable to everybody. Signed-off-by: Knut Petersen Acked-by: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 3 ++- include/linux/fb.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 8068d2f7efe6..3660e51b2612 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2103,7 +2103,8 @@ static int fbcon_switch(struct vc_data *vc) fb_set_var(info, &var); ops->var = info->var; - if (old_info != NULL && old_info != info) { + if (old_info != NULL && (old_info != info || + info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); fbcon_del_cursor_timer(old_info); diff --git a/include/linux/fb.h b/include/linux/fb.h index 55ccaf3706c1..dab3a4decb44 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -732,6 +732,18 @@ struct fb_tile_ops { from userspace */ #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ +/* A driver may set this flag to indicate that it does want a set_par to be + * called every time when fbcon_switch is executed. The advantage is that with + * this flag set you can really be shure that set_par is always called before + * any of the functions dependant on the correct hardware state or altering + * that state, even if you are using some broken X releases. The disadvantage + * is that it introduces unwanted delays to every console switch if set_par + * is slow. It is a good idea to try this flag in the drivers initialization + * code whenever there is a bug report related to switching between X and the + * framebuffer console. + */ +#define FBINFO_MISC_ALWAYS_SETPAR 0x40000 + struct fb_info { int node; int flags; -- cgit v1.2.3 From 7275b4b6bc2f783c135c3f0eeecc4fdc6e788aa8 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:20 -0800 Subject: [PATCH] fbdev: Shift pixel value before entering loop in cfbimageblit In slow imageblit, the pixel value is shifted by a certain amount (dependent on the bpp and endianness) for each iteration. This is inefficient. Better do the shifting once before going into the loop. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/cfbimgblt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index a7770c4f17d0..7a01742a82af 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -162,6 +162,8 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * u32 i, j, l; dst2 = (u32 __iomem *) dst1; + fgcolor <<= LEFT_POS(bpp); + bgcolor <<= LEFT_POS(bpp); for (i = image->height; i--; ) { shift = val = 0; @@ -180,7 +182,6 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * while (j--) { l--; color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor; - color <<= LEFT_POS(bpp); val |= SHIFT_HIGH(color, shift); /* Did the bitshift spill bits to the next long? */ -- cgit v1.2.3 From be0d9b6c7aeaad1683059c00131cabd4c894c17c Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Mon, 12 Dec 2005 22:17:21 -0800 Subject: [PATCH] fbdev: Fix incorrect unaligned access in little-endian machines The drawing function cfbfillrect does not work correctly when access is not unsigned-long aligned. It manifests as extra lines of pixels that are not complete drawn. Reversing the shift operator solves the problem, so I would presume that this bug would manifest only on little endian machines. The function cfbcopyarea may also have this bug. Aligned access should present no problems. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/cfbcopyarea.c | 8 ++++---- drivers/video/cfbfillrect.c | 16 ++++++++-------- drivers/video/cfbimgblt.c | 36 ++++++++++++------------------------ include/linux/fb.h | 12 ++++++++++++ 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index cdc71572cf35..74415325b016 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c @@ -64,8 +64,8 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src int const shift = dst_idx-src_idx; int left, right; - first = ~0UL >> dst_idx; - last = ~(~0UL >> ((dst_idx+n) % bits)); + first = FB_SHIFT_HIGH(~0UL, dst_idx); + last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); if (!shift) { // Same alignment for source and dest @@ -216,8 +216,8 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem shift = dst_idx-src_idx; - first = ~0UL << (bits - 1 - dst_idx); - last = ~(~0UL << (bits - 1 - ((dst_idx-n) % bits))); + first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx); + last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits))); if (!shift) { // Same alignment for source and dest diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index 167d9314e6eb..e5ff62e9cfb8 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c @@ -110,8 +110,8 @@ bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsi if (!n) return; - first = ~0UL >> dst_idx; - last = ~(~0UL >> ((dst_idx+n) % bits)); + first = FB_SHIFT_HIGH(~0UL, dst_idx); + last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); if (dst_idx+n <= bits) { // Single word @@ -167,8 +167,8 @@ bitfill_unaligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, if (!n) return; - first = ~0UL >> dst_idx; - last = ~(~0UL >> ((dst_idx+n) % bits)); + first = FB_SHIFT_HIGH(~0UL, dst_idx); + last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); if (dst_idx+n <= bits) { // Single word @@ -221,8 +221,8 @@ bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat, if (!n) return; - first = ~0UL >> dst_idx; - last = ~(~0UL >> ((dst_idx+n) % bits)); + first = FB_SHIFT_HIGH(~0UL, dst_idx); + last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); if (dst_idx+n <= bits) { // Single word @@ -290,8 +290,8 @@ bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat if (!n) return; - first = ~0UL >> dst_idx; - last = ~(~0UL >> ((dst_idx+n) % bits)); + first = FB_SHIFT_HIGH(~0UL, dst_idx); + last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); if (dst_idx+n <= bits) { // Single word diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 7a01742a82af..910e2338a27e 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -76,18 +76,6 @@ static u32 cfb_tab32[] = { #define FB_WRITEL fb_writel #define FB_READL fb_readl -#if defined (__BIG_ENDIAN) -#define LEFT_POS(bpp) (32 - bpp) -#define SHIFT_HIGH(val, bits) ((val) >> (bits)) -#define SHIFT_LOW(val, bits) ((val) << (bits)) -#define BIT_NR(b) (7 - (b)) -#else -#define LEFT_POS(bpp) (0) -#define SHIFT_HIGH(val, bits) ((val) << (bits)) -#define SHIFT_LOW(val, bits) ((val) >> (bits)) -#define BIT_NR(b) (b) -#endif - static inline void color_imageblit(const struct fb_image *image, struct fb_info *p, u8 __iomem *dst1, u32 start_index, @@ -109,7 +97,7 @@ static inline void color_imageblit(const struct fb_image *image, val = 0; if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); + u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index)); val = FB_READL(dst) & start_mask; shift = start_index; } @@ -119,20 +107,20 @@ static inline void color_imageblit(const struct fb_image *image, color = palette[*src]; else color = *src; - color <<= LEFT_POS(bpp); - val |= SHIFT_HIGH(color, shift); + color <<= FB_LEFT_POS(bpp); + val |= FB_SHIFT_HIGH(color, shift); if (shift >= null_bits) { FB_WRITEL(val, dst++); val = (shift == null_bits) ? 0 : - SHIFT_LOW(color, 32 - shift); + FB_SHIFT_LOW(color, 32 - shift); } shift += bpp; shift &= (32 - 1); src++; } if (shift) { - u32 end_mask = SHIFT_HIGH(~(u32)0, shift); + u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } @@ -162,8 +150,8 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * u32 i, j, l; dst2 = (u32 __iomem *) dst1; - fgcolor <<= LEFT_POS(bpp); - bgcolor <<= LEFT_POS(bpp); + fgcolor <<= FB_LEFT_POS(bpp); + bgcolor <<= FB_LEFT_POS(bpp); for (i = image->height; i--; ) { shift = val = 0; @@ -174,21 +162,21 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * /* write leading bits */ if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); + u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index)); val = FB_READL(dst) & start_mask; shift = start_index; } while (j--) { l--; - color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor; - val |= SHIFT_HIGH(color, shift); + color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; + val |= FB_SHIFT_HIGH(color, shift); /* Did the bitshift spill bits to the next long? */ if (shift >= null_bits) { FB_WRITEL(val, dst++); val = (shift == null_bits) ? 0 : - SHIFT_LOW(color,32 - shift); + FB_SHIFT_LOW(color,32 - shift); } shift += bpp; shift &= (32 - 1); @@ -197,7 +185,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * /* write trailing bits */ if (shift) { - u32 end_mask = SHIFT_HIGH(~(u32)0, shift); + u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } diff --git a/include/linux/fb.h b/include/linux/fb.h index dab3a4decb44..a973be2cfe61 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -833,6 +833,18 @@ struct fb_info { #define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) #define fb_memset memset +#endif + +#if defined (__BIG_ENDIAN) +#define FB_LEFT_POS(bpp) (32 - bpp) +#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) +#define FB_SHIFT_LOW(val, bits) ((val) << (bits)) +#define FB_BIT_NR(b) (7 - (b)) +#else +#define FB_LEFT_POS(bpp) (0) +#define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) +#define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) +#define FB_BIT_NR(b) (b) #endif /* -- cgit v1.2.3 From 50630195bbdfe1ca775d94cd68a5f18bc1b717e4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 13 Dec 2005 02:29:45 -0500 Subject: [libata] mark certain hardware (or drivers) with a no-atapi flag Some hardware does not support the PACKET command at all. Other hardware supports ATAPI, but the driver does something nasty such as calling BUG() when an ATAPI command is issued. For these such cases, we mark them with a new flag, ATA_FLAG_NO_ATAPI. Initial version contributed by Ben Collins. --- drivers/scsi/libata-scsi.c | 7 +++++-- drivers/scsi/sata_mv.c | 3 ++- drivers/scsi/sata_promise.c | 12 ++++++------ drivers/scsi/sata_sx4.c | 3 ++- include/linux/libata.h | 1 + 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 379e87089764..72ddba98f8fb 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -2173,9 +2173,12 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) if (unlikely(!ata_dev_present(dev))) return NULL; - if (!atapi_enabled) { - if (unlikely(dev->class == ATA_DEV_ATAPI)) + if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) { + if (unlikely(dev->class == ATA_DEV_ATAPI)) { + printk(KERN_WARNING "ata%u(%u): WARNING: ATAPI is %s, device ignored.\n", + ap->id, dev->devno, atapi_enabled ? "not supported with this driver" : "disabled"); return NULL; + } } return dev; diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index ab7432a5778e..9321cdf45680 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -86,7 +86,8 @@ enum { MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), + ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_NO_ATAPI), MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, CRQB_FLAG_READ = (1 << 0), diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 8a8e3e3ef0ed..2691625f9bce 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -70,6 +70,9 @@ enum { PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ PDC_RESET = (1 << 11), /* HDMA reset */ + + PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | + ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI, }; @@ -162,8 +165,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_2037x */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -173,8 +175,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_20319 */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -184,8 +185,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_20619 */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | - ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index dcc3ad9a9d6e..ac7b0d819ebc 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -220,7 +220,8 @@ static struct ata_port_info pdc_port_info[] = { { .sht = &pdc_sata_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + ATA_FLAG_SRST | ATA_FLAG_MMIO | + ATA_FLAG_NO_ATAPI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ diff --git a/include/linux/libata.h b/include/linux/libata.h index f2dbb684ce9e..41ea7dbc1755 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -122,6 +122,7 @@ enum { ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once * proper HSM is in place. */ ATA_FLAG_DEBUGMSG = (1 << 10), + ATA_FLAG_NO_ATAPI = (1 << 11), /* No ATAPI support */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ -- cgit v1.2.3 From 98684a9d91bceff829b6dc7adf0f662d59cfa6e3 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 13 Dec 2005 11:35:22 -0500 Subject: [netdrvr skge] fix build --- drivers/net/skge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8b6e2a11e28d..00d683063c01 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2280,7 +2280,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) } if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { - if (!netif_stopped(dev)) { + if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", -- cgit v1.2.3 From 83bab9a4bbf91af93f45233dc288c4d26308e281 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 13 Dec 2005 02:58:07 +0100 Subject: [PATCH] allow KOBJECT_UEVENT=n only if EMBEDDED KOBJECT_UEVENT=n seems to be a common pitfall for udev users in 2.6.14 . -mm already contains a bigger patch removing this option that is IMHO too big for being applied now to 2.6.15-rc. This patch simply allows KOBJECT_UEVENT=n only if EMBEDDED. Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index ea097e0a9c02..59344616f477 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -206,7 +206,7 @@ config HOTPLUG outside the kernel tree does. Such modules require Y here. config KOBJECT_UEVENT - bool "Kernel Userspace Events" + bool "Kernel Userspace Events" if EMBEDDED depends on NET default y help -- cgit v1.2.3 From eed66cfcbbea851c97e287440d940286fce3f829 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 13 Dec 2005 10:41:49 -0800 Subject: [IA64] Split 16-bit severity field in sal_log_record_header ERR_SEVERITY item is defined as a 8 bits item in SAL documentation ($B.2.1 rev december 2003), but as an u16 in sal.h. This has the side effect that current code in mca.c may not call ia64_sal_clear_state_info() upon receiving corrected platform errors if there are bits set in the validation byte. Reported by Xavier Bru. Signed-off-by: Tony Luck --- include/asm-ia64/sal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index 29df88bdd2bc..313cad0628d0 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h @@ -320,7 +320,8 @@ typedef struct sal_log_timestamp { typedef struct sal_log_record_header { u64 id; /* Unique monotonically increasing ID */ sal_log_revision_t revision; /* Major and Minor revision of header */ - u16 severity; /* Error Severity */ + u8 severity; /* Error Severity */ + u8 validation_bits; /* 0: platform_guid, 1: !timestamp */ u32 len; /* Length of this error log in bytes */ sal_log_timestamp_t timestamp; /* Timestamp */ efi_guid_t platform_guid; /* Unique OEM Platform ID */ -- cgit v1.2.3 From 0910b444bcd7ea7f437a3ff48e0e3d2495ead22e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 13 Dec 2005 11:39:05 -0800 Subject: Expose "Optimize for size" option for everybody Let's put my money where my mouth is. Smaller code is almost always faster, if only because a single I$ miss ends up leaving a lot of cycles to make up for. And system software - kernels in particular - are known for taking more cache misses than most other kinds. On my random config, this made the kernel about 10% smaller, and lmbench seems to say that it's pretty uniformly faster too. Your milage may vary. Signed-off-by: Linus Torvalds --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index 59344616f477..be74adb389ea 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -339,7 +339,7 @@ config EPOLL support for epoll family of system calls. config CC_OPTIMIZE_FOR_SIZE - bool "Optimize for size" if EMBEDDED + bool "Optimize for size" default y if ARM || H8300 help Enabling this option will pass "-Os" instead of "-O2" to gcc -- cgit v1.2.3 From 322e079f1b606e46b79bb8b8e6cf6110b5f2aa3f Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 29 Nov 2005 23:08:40 -0500 Subject: [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; -- cgit v1.2.3 From 381291b7d3e17ac966498312dc571dcca1b93efc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:08:21 -0800 Subject: [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); /* -- cgit v1.2.3 From 6a9eba15f51c56da637e45ea1316eaa2a848986a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:08:58 -0800 Subject: [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; -- cgit v1.2.3 From 16fe9d74f14ed74af778c5db7f9129e29916f4a7 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:09:54 -0800 Subject: [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 -- cgit v1.2.3 From 6921d201f77e14848df2eaa597e26525f468abea Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 13 Dec 2005 21:15:53 -0800 Subject: [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 */ -- cgit v1.2.3 From 664d22ab954de54e52e0f71103a89c7a78738adc Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Tue, 13 Dec 2005 17:03:36 -0800 Subject: [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 -- cgit v1.2.3 From 118c71bcacce82a4317c9bd99c6a15af14020aee Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Tue, 13 Dec 2005 17:03:37 -0800 Subject: [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) -- cgit v1.2.3 From fb79ffa4ddbe3f6f30fdb8429b5bad84d25ae6ef Mon Sep 17 00:00:00 2001 From: Ole Reinhardt Date: Tue, 13 Dec 2005 17:03:38 -0800 Subject: [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; } -- cgit v1.2.3 From cd6104572bca9e4afe0dcdb8ecd65ef90b01297b Mon Sep 17 00:00:00 2001 From: Adam Kropelin Date: Tue, 13 Dec 2005 17:03:39 -0800 Subject: [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); -- cgit v1.2.3 From c9526497cf03ee775c3a6f8ba62335735f98de7a Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 9 Dec 2005 17:45:22 -0500 Subject: [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; - - 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; + if (SCpnt->timeout_per_command) + timeout = SCpnt->timeout_per_command; - 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 */ -- cgit v1.2.3 From a1493d9cd1aaed06860d128a37df1bdfbc61f7c8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Dec 2005 22:59:36 -0800 Subject: [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); -- cgit v1.2.3 From 2edc2689f8183dd21c45621a01580b340ac420ba Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 13 Dec 2005 22:59:50 -0800 Subject: [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...) -- cgit v1.2.3 From 45f8245b972e360c19aec9032e2a2033b8ac3719 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 14 Dec 2005 14:57:35 +0000 Subject: [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) { -- cgit v1.2.3 From 27af4cfd11883073359bd5acab1962b0fa96a3bf Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Wed, 14 Dec 2005 06:58:05 -0600 Subject: [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 } /* -- cgit v1.2.3 From 1542272a60ab9c0655a13ead8b7d7a661365f9fb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Dec 2005 12:55:24 -0800 Subject: [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 -- cgit v1.2.3 From c2e2611425a956d25d2948c5d95d3848c4db1257 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 14 Dec 2005 22:04:22 +0000 Subject: [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]; -- cgit v1.2.3 From a388442c3798a345d131ff8b9d6dea0bfda3fefc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 14 Dec 2005 16:23:16 -0800 Subject: [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. */ -- cgit v1.2.3 From deb5e5c0c68e59b1bf9ede66da9e6a89f6557595 Mon Sep 17 00:00:00 2001 From: Jeremy Higdon Date: Thu, 15 Dec 2005 02:10:35 +0100 Subject: [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; -- cgit v1.2.3 From ceef833bae05e393859f1946a9802fb61f0febdf Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 15 Dec 2005 02:11:55 +0100 Subject: [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 -- cgit v1.2.3 From 38f9d412be1ed29ee3b41782f22fd85b1c95fbed Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 15 Dec 2005 02:12:53 +0100 Subject: [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. -- cgit v1.2.3 From 65e5f2e3b457b6b20a5c4481312189d141a33d24 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 15 Dec 2005 02:16:18 +0100 Subject: [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 *); -- cgit v1.2.3 From 8f29e650bffc1e22ed6b2d0b321bc77627f3bb7a Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Thu, 15 Dec 2005 02:17:46 +0100 Subject: [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 | 1498 ++++++++++------------------- include/asm-mips/mach-au1x00/au1xxx_ide.h | 17 +- 4 files changed, 543 insertions(+), 983 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" - -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; - -/* - * local I/O functions - */ -u8 auide_inb(unsigned long port) -{ - return (au_readb(port)); -} +#define DRV_AUTHOR "Enrico Walther / Pete Popov " -u16 auide_inw(unsigned long port) -{ - return (au_readw(port)); -} +/* enable the burstmode in the dbdma */ +#define IDE_AU1XXX_BURSTMODE 1 -u32 auide_inl(unsigned long port) -{ - return (au_readl(port)); -} +static _auide_hwif auide_hwif; +static int dbdma_init_done; -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; - - 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) +void auide_insw(unsigned long port, void *addr, u32 count) { - return (au_writeb(addr, port)); -} + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; -void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port) -{ - return (au_writeb(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_outw(u16 addr, unsigned long port) +void auide_outsw(unsigned long port, void *addr, u32 count) { - return (au_writew(addr, port)); -} + _auide_hwif *ahwif = &auide_hwif; + chan_tab_t *ctp; + au1x_ddma_desc_t *dp; -void auide_outl(u32 addr, unsigned long port) -{ - return (au_writel(addr, port)); + 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); } -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; - - 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; - - /* 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); - - spin_lock_irqsave(&ide_tune_drive_spin_lock, flags); - - mem_sttime = 0; - mem_stcfg = au_readl(MEM_STCFG2); - - /* 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; - - au_writel(mem_sttime,MEM_STTIME2); - au_writel(mem_stcfg,MEM_STCFG2); - break; - - 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; - - 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 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; - - break; - - 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; - } - - au_writel(mem_sttime,MEM_STTIME2); - au_writel(mem_stcfg,MEM_STCFG2); - - spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags); - - speed = pio + XFER_PIO_0; - ide_config_drive_speed(drive, 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); + + printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n", + drive->name, pio); + + mem_sttime = 0; + mem_stcfg = au_readl(MEM_STCFG2); + + /* set pio mode! */ + switch(pio) { + case 0: + mem_sttime = SBC_IDE_TIMING(PIO0); + + /* 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; + + case 1: + mem_sttime = SBC_IDE_TIMING(PIO1); + + /* 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: + mem_sttime = SBC_IDE_TIMING(PIO2); + + /* 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 3: + mem_sttime = SBC_IDE_TIMING(PIO3); + + /* 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; + + break; + + case 4: + mem_sttime = SBC_IDE_TIMING(PIO4); + + /* 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; + int mem_sttime; + int mem_stcfg; + unsigned long mode; + #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - struct hd_driveid *id = drive->id; - - /* - * 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; - } - } + 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; - - 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; - - 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_0; - break; + case XFER_MW_DMA_2: + mem_sttime = SBC_IDE_TIMING(MDMA2); + + /* 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_2; + break; + case XFER_MW_DMA_1: + mem_sttime = SBC_IDE_TIMING(MDMA1); + + /* 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; - } - - /* - * 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); + default: + return 1; + } + + if (ide_config_drive_speed(drive, mode)) + return 1; - spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags); + au_writel(mem_sttime,MEM_STTIME2); + au_writel(mem_stcfg,MEM_STCFG2); - 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); - - struct request *rq = HWGROUP(drive)->rq; - - _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; - struct scatterlist *sg; - - iswrite = (rq_data_dir(rq) == WRITE); - /* Save for interrupt context */ - ahwif->drive = drive; - - /* Build sglist */ - hwif->sg_nents = i = auide_build_sglist(drive, rq); - - if (!i) - return 0; - - /* 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); - - 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; - } - - /* 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__); + int i, iswrite, count = 0; + ide_hwif_t *hwif = HWIF(drive); + + struct request *rq = HWGROUP(drive)->rq; + + _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data; + struct scatterlist *sg; + + iswrite = (rq_data_dir(rq) == WRITE); + /* Save for interrupt context */ + ahwif->drive = drive; + + /* Build sglist */ + hwif->sg_nents = i = auide_build_sglist(drive, rq); + + if (!i) + return 0; + + /* 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); + + 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; + } + + /* 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__); } - } 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__); - - if (drive->media != ide_disk) - return 1; - - if (!auide_build_dmatable(drive)) - /* try PIO instead of DMA */ - return 1; +{ + struct request *rq = HWGROUP(drive)->rq; - drive->waiting_for_dma = 1; + if (!auide_build_dmatable(drive)) { + ide_map_sg(drive, rq); + return 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? */ + + if ( auide_hwif.black_list ) { + drive->using_dma = 0; + + /* Borrowed the warning message from ide-dma.c */ - return HWIF(drive)->ide_dma_host_on(drive); + 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; +} + +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ - _auide_hwif *ahwif = (_auide_hwif*)param; - ahwif->drive->waiting_for_dma = 0; - return; +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; -static int auide_ddma_init( _auide_hwif *auide ) -{ -// printk("%s\n", __FUNCTION__); + dev_id = AU1XXX_ATA_DDMA_REQ; - 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 + 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'"); + } - /* 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 ); + /* 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 - /* 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 + +static int auide_ddma_init( _auide_hwif *auide ) +{ + dbdev_tab_t source_dev_tab; + int flags; -#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); +#ifdef IDE_AU1XXX_BURSTMODE + flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE; +#else + flags = DEV_FLAGS_SYNC; #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; + /* 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 ); + + 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; - - /* fixme */ - for (i = 0; i < IDE_CONTROL_OFFSET; i++) { - *ata_regs++ = (ide_ioreg_t) ahwif->regbase - + (ide_ioreg_t)(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); + int i; + unsigned long *ata_regs = hw->io_ports; + + /* 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 = 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]; + /* FIXME: This might possibly break PCMCIA IDE devices */ + + hwif = &ide_hwifs[pdev->id]; hw_regs_t *hw = &hwif->hw; - hwif->irq = hw->irq = ahwif->irq; - hwif->chipset = ide_au1xxx; + hwif->irq = hw->irq = ahwif->irq; + hwif->chipset = ide_au1xxx; - auide_setup_ports(hw, ahwif); + 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 = 0; + hwif->drives[0].unmask = 1; + hwif->drives[1].unmask = 1; + + /* hold should be on in all cases */ + hwif->hold = 1; + hwif->mmio = 2; + + /* 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->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; - - /* 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; - - hwif->tuneproc = &auide_tune_drive; - hwif->speedproc = &auide_tune_chipset; + + 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_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->drives[0].using_dma = 1; - hwif->drives[1].using_dma = 1; + 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->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + hwif->atapi_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->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 */ -#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 */ - - /*Register Driver with PM Framework*/ -#ifdef CONFIG_PM - auide_hwif.pm.lock = SPIN_LOCK_UNLOCKED; - auide_hwif.pm.stopped = 0; - - 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"); + 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].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */ #endif + hwif->drives[0].no_io_32bit = 1; - auide_hwif.hwif = hwif; - hwif->hwif_data = &auide_hwif; + 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 -- cgit v1.2.3 From d36fef6f5aa4a6a1f44490455393a5b22137a6cd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:19:20 +0100 Subject: [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; -- cgit v1.2.3 From 517bd1d5eac739a7f398058a9524386667fff032 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:19:57 +0100 Subject: [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 *); -- cgit v1.2.3 From 7b4df9ece9b4c4a754bd1f5603cdabff26b987e5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:20:15 +0100 Subject: [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; -- cgit v1.2.3 From 0afaa4fc4abc773ce129f41009a50eeecf3aa50c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 15 Dec 2005 02:20:49 +0100 Subject: [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. */ -- cgit v1.2.3 From c45b4f1f1e149c023762ac4be166ead1818cefef Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 14 Dec 2005 18:52:21 -0800 Subject: 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 -- cgit v1.2.3 From ea54c96c04cfd9fec881e403d8f7931b47f7b2a6 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Wed, 14 Dec 2005 21:47:00 -0500 Subject: [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 }, -- cgit v1.2.3 From 5d5e815618c4a8b53806845268c951201d14af6e Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 14 Dec 2005 14:38:36 -0500 Subject: [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); -- cgit v1.2.3 From 2499604960fff307fe99ff4d4363c50eaa69235a Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 14 Dec 2005 14:38:05 -0500 Subject: [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) -- cgit v1.2.3 From f8ad23a401d41f90cb377035d206b41de0699a0b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:44:18 -0500 Subject: [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; -- cgit v1.2.3 From b7c690b52f424574f7ac8c607e71e9f5c283a557 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:50:56 -0500 Subject: [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); } -- cgit v1.2.3 From bc05d83bbf20a32eb24624726d1027aa960a573c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:51:43 -0500 Subject: [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; } -- cgit v1.2.3 From fec607fff973b1d7805c1bbce5834690857e7801 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:54:54 -0500 Subject: [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); -- cgit v1.2.3 From c316ef0494eec2d08df2f083fc06fc06a6fd48c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:55:44 -0500 Subject: [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; -- cgit v1.2.3 From e4fe342f932346a306f98f5401ad510b890c0a15 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 4 Dec 2005 18:48:45 -0500 Subject: [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) -- cgit v1.2.3 From a32972965e23471f0762a1136f80990ebf72406a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 05:56:39 -0500 Subject: [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) */ -- cgit v1.2.3 From 80ce8baf5da730c87194e2e38a4cfca0254f9599 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 6 Dec 2005 06:04:55 -0500 Subject: [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; -- cgit v1.2.3 From b53cb2a4ab276796ad299597d6e7e2317b514ca8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:19 +0000 Subject: [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; -- cgit v1.2.3 From 51bfb75b0b2652f60ab1200627e9041f4624c819 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:24 +0000 Subject: [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; -- cgit v1.2.3 From 37eb47ed445f4ca1247f3c7b600c0885c2ca8c31 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:29 +0000 Subject: [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; -- cgit v1.2.3 From 53b3de1ea2f81de7050f247cd7fc63863887e8d7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:34 +0000 Subject: [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) -- cgit v1.2.3 From 8bcc247617deaf229962e9d663c69e65523519ab Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:39 +0000 Subject: [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; -- cgit v1.2.3 From 8b8a4e33e4a320735f353a092013b314f142493d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:44 +0000 Subject: [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) -- cgit v1.2.3 From b16b88e55d808a6324d5ff02d8c686f7884870f8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:50 +0000 Subject: [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 -- cgit v1.2.3 From c4aa02eb3939c5004782454434e4d50de471b53d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:17:55 +0000 Subject: [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) -- cgit v1.2.3 From 5ad9201be7f7d52d712fe3c3e841fdc19216ede1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:00 +0000 Subject: [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); -- cgit v1.2.3 From e896fd9861181140617aa9ff3a54dac25e46351d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:05 +0000 Subject: [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, -- cgit v1.2.3 From cd0306656c15f355e0e533cc0f08691bb98ca912 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:10 +0000 Subject: [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 -- cgit v1.2.3 From d22043940eb8d660df9a94e8e439ab4d3d16edab Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:15 +0000 Subject: [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 */ -- cgit v1.2.3 From 538bacf8a4802d209f955726b66891b8a921dabf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:20 +0000 Subject: [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(); -- cgit v1.2.3 From 78d9955bb06493e7bd78e43dfdc17fb5f1dc59b6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:25 +0000 Subject: [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; -- cgit v1.2.3 From d3a880e1ff6713b4c846e4d2526a8c7e6ad8469c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:30 +0000 Subject: [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; -- cgit v1.2.3 From b3e5b5b2277f9c047082dcb309f665fe8b5706c1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:40 +0000 Subject: [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) -- cgit v1.2.3 From 94299171dd269aab0c97f6254cedb381f10e6348 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:45 +0000 Subject: [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."); -- cgit v1.2.3 From e17f008bbeabcd1302d6cf4b5b9659be6d80f1db Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:50 +0000 Subject: [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, \ -- cgit v1.2.3 From 7877327d9c360ac91f22e4c7f98bcb10c0180969 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:18:55 +0000 Subject: [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; -- cgit v1.2.3 From 833882b452046d3d5028f6293a0a6d6d3c1eee3c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:00 +0000 Subject: [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) -- cgit v1.2.3 From 81f0a91e8f58a7784afe39cda9ac47e9231412a4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:05 +0000 Subject: [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) -- cgit v1.2.3 From ebbd1bce79b3b4778d9e1914a22c42fcfa869cd9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 15 Dec 2005 09:19:10 +0000 Subject: [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 */ -- cgit v1.2.3 From 7767e126ca0f32cd0438455fdd9650f909d2eeb3 Mon Sep 17 00:00:00 2001 From: Paolo Galtieri Date: Thu, 15 Dec 2005 12:34:28 -0800 Subject: [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) -- cgit v1.2.3 From 2f40fb72a2121da44c35f2588ee9abce1dffa2a9 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 15 Dec 2005 12:34:29 -0800 Subject: [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) { -- cgit v1.2.3 From 7b6666530e2736f190a2629c8abe34275054449f Mon Sep 17 00:00:00 2001 From: Sergei Shtylylov Date: Thu, 15 Dec 2005 12:34:30 -0800 Subject: [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; -- cgit v1.2.3 From 281ab031a8c9e5b593142eb4ec59a87faae8676a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 16 Dec 2005 16:52:22 +1100 Subject: [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) -- cgit v1.2.3 From 4d7672b46244abffea1953e55688c0ea143dd617 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Dec 2005 10:21:23 -0800 Subject: 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; } -- cgit v1.2.3 From dfded4ae71080b53798c7bbf4628a9b22d1e3e8b Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Fri, 16 Dec 2005 11:08:43 -0800 Subject: [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; } -- cgit v1.2.3 From 52f975ea21e28871a371c2d941e13d64c9f8cd66 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 16 Dec 2005 11:08:48 -0800 Subject: [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/ - -- cgit v1.2.3 From 42f3ab42875a52af7e711803bfb8d8d7cca84c1c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 16 Dec 2005 11:08:55 -0800 Subject: [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); } -- cgit v1.2.3 From 42245e65f356ed54fdf7a1f9a0095e0bc40f73a3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 16 Dec 2005 11:09:01 -0800 Subject: [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; -- cgit v1.2.3