aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/advansys.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-02-07 19:50:08 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-11 11:20:53 -0500
commit7d5d408c77cee95d1380511de46b7a4c8dc2211d (patch)
treebec3464f501145718b2426efde10b02229de4552 /drivers/scsi/advansys.c
parent19af35546de68c872dcb687613e0902a602cb20e (diff)
[SCSI] advansys: fix overrun_buf aligned bug
struct asc_dvc_var needs overrun buffer to be placed on an 8 byte boundary. advansys defines struct asc_dvc_var: struct asc_dvc_var { ... uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); The problem is that struct asc_dvc_var is placed on shost->hostdata. So if the hostdata is not on an 8 byte boundary, the advansys crashes. The hostdata is placed on a sizeof(unsigned long) boundary so the 8 byte boundary is not garanteed with x86_32. With 2.6.23 and 2.6.24, the hostdata is on an 8 byte boundary by chance, but with the current git, it's not. This patch removes overrun_buf static array and use kzalloc. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r--drivers/scsi/advansys.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index ccef891d642f..3c2d6888bb8c 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -566,7 +566,7 @@ typedef struct asc_dvc_var {
566 ASC_SCSI_BIT_ID_TYPE unit_not_ready; 566 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
567 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; 567 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
568 ASC_SCSI_BIT_ID_TYPE start_motor; 568 ASC_SCSI_BIT_ID_TYPE start_motor;
569 uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); 569 uchar *overrun_buf;
570 dma_addr_t overrun_dma; 570 dma_addr_t overrun_dma;
571 uchar scsi_reset_wait; 571 uchar scsi_reset_wait;
572 uchar chip_no; 572 uchar chip_no;
@@ -13833,6 +13833,12 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
13833 */ 13833 */
13834 if (ASC_NARROW_BOARD(boardp)) { 13834 if (ASC_NARROW_BOARD(boardp)) {
13835 ASC_DBG(2, "AscInitAsc1000Driver()\n"); 13835 ASC_DBG(2, "AscInitAsc1000Driver()\n");
13836
13837 asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
13838 if (!asc_dvc_varp->overrun_buf) {
13839 ret = -ENOMEM;
13840 goto err_free_wide_mem;
13841 }
13836 warn_code = AscInitAsc1000Driver(asc_dvc_varp); 13842 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
13837 13843
13838 if (warn_code || asc_dvc_varp->err_code) { 13844 if (warn_code || asc_dvc_varp->err_code) {
@@ -13840,8 +13846,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
13840 "warn 0x%x, error 0x%x\n", 13846 "warn 0x%x, error 0x%x\n",
13841 asc_dvc_varp->init_state, warn_code, 13847 asc_dvc_varp->init_state, warn_code,
13842 asc_dvc_varp->err_code); 13848 asc_dvc_varp->err_code);
13843 if (asc_dvc_varp->err_code) 13849 if (asc_dvc_varp->err_code) {
13844 ret = -ENODEV; 13850 ret = -ENODEV;
13851 kfree(asc_dvc_varp->overrun_buf);
13852 }
13845 } 13853 }
13846 } else { 13854 } else {
13847 if (advansys_wide_init_chip(shost)) 13855 if (advansys_wide_init_chip(shost))
@@ -13894,6 +13902,7 @@ static int advansys_release(struct Scsi_Host *shost)
13894 dma_unmap_single(board->dev, 13902 dma_unmap_single(board->dev,
13895 board->dvc_var.asc_dvc_var.overrun_dma, 13903 board->dvc_var.asc_dvc_var.overrun_dma,
13896 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); 13904 ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
13905 kfree(board->dvc_var.asc_dvc_var.overrun_buf);
13897 } else { 13906 } else {
13898 iounmap(board->ioremap_addr); 13907 iounmap(board->ioremap_addr);
13899 advansys_wide_free_mem(board); 13908 advansys_wide_free_mem(board);