spi_fpga_init: fix slab corruption bug

fix this bug:
[   74.920000] bt turn on power
bcm4329
patch_plus -d /etc/bluez/bcm4325/BCM4329B1_TestOnly_0237_26MHz_SEMCO_B23.hcd /dev/ttySPI0 bcm4325 1500000
speed of uart to :1500000
[   75.330000] uart->index=0
[   75.330000] baud=115200,quot=0x34
[   75.340000] baud=115200,quot=0x34
[   75.340000] Slab corruption: size-32 start=cc3b3660, len=32
[   75.340000] 010: 6b 6b 6b 6b b4 36 3b cc 6b 6b 6b 6b 6b 6b 6b a5
[   75.370000] Prev obj: start=cc3b3640, len=32
[   75.370000] 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b
[   75.370000] 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5
[   75.370000] Next obj: start=cc3b3680, len=32
[   75.370000] 000: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b
[   75.370000] 010: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5
This commit is contained in:
黄涛
2010-10-12 17:52:55 +08:00
parent 1a48e7059e
commit cf60841e02

View File

@@ -71,36 +71,32 @@ static void spi_fpga_trans_work_handler(struct work_struct *work)
{
struct spi_fpga_port *port =
container_of(work, struct spi_fpga_port, fpga_trans_work);
unsigned long flags;
spin_lock_irqsave(&port->work_lock, flags);
while (!list_empty(&port->trans_queue))
{
spin_unlock_irqrestore(&port->work_lock, flags);
struct spi_fpga_transfer *t = NULL, *tmp;
list_for_each_entry_safe(t, tmp, &port->trans_queue, queue)
{
if (t->id == 0)
break;
DBG("%s:id=%d,txbuf=0x%x\n",__FUNCTION__,t->id,(int)t->txbuf);
switch(t->id)
{
case ID_SPI_FPGA_WRITE:
spi_write(port->spi, t->txbuf, t->n_tx);
break;
default:
break;
}
kfree(t->txbuf);
kfree(t);
}
while (1) {
unsigned long flags;
struct spi_fpga_transfer *t = NULL;
spin_lock_irqsave(&port->work_lock, flags);
list_del_init(&port->trans_queue);
if (!list_empty(&port->trans_queue)) {
t = list_first_entry(&port->trans_queue, struct spi_fpga_transfer, queue);
list_del(&t->queue);
}
spin_unlock_irqrestore(&port->work_lock, flags);
if (!t) // trans_queue empty
break;
DBG("%s:id=%d,txbuf=0x%x\n",__FUNCTION__,t->id,(int)t->txbuf);
switch (t->id) {
case ID_SPI_FPGA_WRITE:
spi_write(port->spi, t->txbuf, t->n_tx);
break;
default:
break;
}
kfree(t->txbuf);
kfree(t);
}
spin_unlock_irqrestore(&port->work_lock, flags);
}
int spi_write_work(struct spi_device *spi, u8 *buf, size_t len)
@@ -129,8 +125,8 @@ int spi_write_work(struct spi_device *spi, u8 *buf, size_t len)
spin_lock_irqsave(&port->work_lock, flags);
list_add_tail(&t->queue, &port->trans_queue);
queue_work(port->fpga_trans_workqueue, &port->fpga_trans_work);
spin_unlock_irqrestore(&port->work_lock, flags);
queue_work(port->fpga_trans_workqueue, &port->fpga_trans_work);
return 0;
@@ -685,43 +681,43 @@ static int spi_fpga_wait_suspend(struct spi_fpga_port *port)
}
return -1;
}
static void fpga_close_power_support(void)
{
//cmmb power down
gpio_request(FPGA_PIO4_03, NULL);
gpio_direction_output(FPGA_PIO4_03,GPIO_LOW);
gpio_free(FPGA_PIO4_03);
gpio_request(FPGA_PIO2_09, NULL);
gpio_direction_output(FPGA_PIO2_09,GPIO_LOW);
gpio_free(FPGA_PIO2_09);
gpio_request(FPGA_PIO2_06, NULL);
gpio_direction_output(FPGA_PIO2_06,GPIO_LOW);
gpio_free(FPGA_PIO2_06);
//KEY LED control
gpio_request(FPGA_PIO1_13, NULL);
gpio_direction_output(FPGA_PIO1_13,GPIO_LOW);
gpio_free(FPGA_PIO1_13);
}
static void fpga_open_power_support(void)
{
//cmmb do not control here
//KEY LED resume
gpio_request(FPGA_PIO1_13, NULL);
gpio_direction_output(FPGA_PIO1_13,GPIO_HIGH);
gpio_free(FPGA_PIO1_13);
}
static void fpga_close_power_support(void)
{
//cmmb power down
gpio_request(FPGA_PIO4_03, NULL);
gpio_direction_output(FPGA_PIO4_03,GPIO_LOW);
gpio_free(FPGA_PIO4_03);
gpio_request(FPGA_PIO2_09, NULL);
gpio_direction_output(FPGA_PIO2_09,GPIO_LOW);
gpio_free(FPGA_PIO2_09);
gpio_request(FPGA_PIO2_06, NULL);
gpio_direction_output(FPGA_PIO2_06,GPIO_LOW);
gpio_free(FPGA_PIO2_06);
//KEY LED control
gpio_request(FPGA_PIO1_13, NULL);
gpio_direction_output(FPGA_PIO1_13,GPIO_LOW);
gpio_free(FPGA_PIO1_13);
}
static void fpga_open_power_support(void)
{
//cmmb do not control here
//KEY LED resume
gpio_request(FPGA_PIO1_13, NULL);
gpio_direction_output(FPGA_PIO1_13,GPIO_HIGH);
gpio_free(FPGA_PIO1_13);
}
static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)
{
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
fpga_close_power_support( );
struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
int ret;
fpga_close_power_support( );
ret = spi_fpga_wait_suspend(port);
if(!ret)
{