Skip to content

Commit 864db4d

Browse files
Amitkumar KarwarKalle Valo
authored andcommitted
rsi: fix kernel panic observed on 64bit machine
Following kernel panic is observed on 64bit machine while loading the driver. It is fixed if we pass dynamically allocated memory to SDIO for DMA. BUG: unable to handle kernel paging request at ffffeb04000172e0 IP: sg_miter_stop+0x56/0x70 PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI Modules linked in: rsi_sdio(OE+) rsi_91x(OE) btrsi(OE) rfcomm bluetooth ecdh_generic mac80211 mmc_block fuse xt_CHECKSUM iptable_mangle drm_kms_helper mmc_core serio_raw drm firewire_ohci tg3 CPU: 0 PID: 4003 Comm: insmod Tainted: G OE 4.16.0-rc1+ frank-w#27 Hardware name: Dell Inc. Latitude E5500 /0DW634, BIOS A19 06/13/2013 RIP: 0010:sg_miter_stop+0x56/0x70 RSP: 0018:ffff88007d003e78 EFLAGS: 00010002 RAX: 0000000000000003 RBX: 0000000000000004 RCX: 0000000000000000 RDX: ffffeb04000172c0 RSI: ffff88002f58002c RDI: ffff88007d003e80 RBP: 0000000000000004 R08: ffff88007d003e80 R09: 0000000000000008 R10: 0000000000000003 R11: 0000000000000001 R12: 0000000000000004 R13: ffff88002f580028 R14: 0000000000000000 R15: 0000000000000004 FS: 00007f35c29db700(0000) GS:ffff88007d000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffeb04000172e0 CR3: 000000007038e000 CR4: 00000000000406f0 Call Trace: <IRQ> sg_copy_buffer+0xc6/0xf0 sdhci_tasklet_finish+0x170/0x260 [sdhci] tasklet_action+0xf4/0x100 __do_softirq+0xef/0x26e irq_exit+0xbe/0xd0 do_IRQ+0x4a/0xc0 common_interrupt+0xa2/0xa2 </IRQ> Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
1 parent 90b12ae commit 864db4d

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

drivers/net/wireless/rsi/rsi_91x_sdio.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -653,19 +653,22 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
653653
u32 *read_buf, u16 size)
654654
{
655655
u32 addr_on_bus, *data;
656-
u32 align[2] = {};
657656
u16 ms_addr;
658657
int status;
659658

660-
data = PTR_ALIGN(&align[0], 8);
659+
data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
660+
if (!data)
661+
return -ENOMEM;
662+
663+
data = PTR_ALIGN(data, 8);
661664

662665
ms_addr = (addr >> 16);
663666
status = rsi_sdio_master_access_msword(adapter, ms_addr);
664667
if (status < 0) {
665668
rsi_dbg(ERR_ZONE,
666669
"%s: Unable to set ms word to common reg\n",
667670
__func__);
668-
return status;
671+
goto err;
669672
}
670673
addr &= 0xFFFF;
671674

@@ -683,7 +686,7 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
683686
(u8 *)data, 4);
684687
if (status < 0) {
685688
rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
686-
return status;
689+
goto err;
687690
}
688691
if (size == 2) {
689692
if ((addr & 0x3) == 0)
@@ -705,17 +708,23 @@ static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
705708
*read_buf = *data;
706709
}
707710

708-
return 0;
711+
err:
712+
kfree(data);
713+
return status;
709714
}
710715

711716
static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
712717
unsigned long addr,
713718
unsigned long data, u16 size)
714719
{
715-
unsigned long data1[2], *data_aligned;
720+
unsigned long *data_aligned;
716721
int status;
717722

718-
data_aligned = PTR_ALIGN(&data1[0], 8);
723+
data_aligned = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
724+
if (!data_aligned)
725+
return -ENOMEM;
726+
727+
data_aligned = PTR_ALIGN(data_aligned, 8);
719728

720729
if (size == 2) {
721730
*data_aligned = ((data << 16) | (data & 0xFFFF));
@@ -734,6 +743,7 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
734743
rsi_dbg(ERR_ZONE,
735744
"%s: Unable to set ms word to common reg\n",
736745
__func__);
746+
kfree(data_aligned);
737747
return -EIO;
738748
}
739749
addr = addr & 0xFFFF;
@@ -743,12 +753,12 @@ static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
743753
(adapter,
744754
(addr | RSI_SD_REQUEST_MASTER),
745755
(u8 *)data_aligned, size);
746-
if (status < 0) {
756+
if (status < 0)
747757
rsi_dbg(ERR_ZONE,
748758
"%s: Unable to do AHB reg write\n", __func__);
749-
return status;
750-
}
751-
return 0;
759+
760+
kfree(data_aligned);
761+
return status;
752762
}
753763

754764
/**

drivers/net/wireless/rsi/rsi_sdio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ enum sdio_interrupt_type {
4646
#define PKT_BUFF_AVAILABLE 1
4747
#define FW_ASSERT_IND 2
4848

49+
#define RSI_MASTER_REG_BUF_SIZE 12
50+
4951
#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3
5052
#define RSI_FN1_INT_REGISTER 0xf9
5153
#define RSI_INT_ENABLE_REGISTER 0x04

0 commit comments

Comments
 (0)