X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Faacraid%2Fcommctrl.c;h=da1d3a9212f8083da498919fb956bc0c44b9eea7;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=47fefca72695d02f3959b7a4e5c846a9c611c9bf;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 47fefca72..da1d3a921 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -38,6 +38,8 @@ #include #include #include +#include /* ssleep prototype */ +#include #include #include @@ -138,7 +140,8 @@ cleanup: fibptr->hw_fib_pa = hw_fib_pa; fibptr->hw_fib = hw_fib; } - aac_fib_free(fibptr); + if (retval != -EINTR) + aac_fib_free(fibptr); return retval; } @@ -293,6 +296,16 @@ return_fib: status = 0; } else { spin_unlock_irqrestore(&dev->fib_lock, flags); + /* If someone killed the AIF aacraid thread, restart it */ + status = !dev->aif_thread; + if (status && !dev->in_reset && dev->queues && dev->fsa_dev) { + /* Be paranoid, be very paranoid! */ + kthread_stop(dev->thread); + ssleep(1); + dev->aif_thread = 0; + dev->thread = kthread_run(aac_command_thread, dev, dev->name); + ssleep(1); + } if (f.wait) { if(down_interruptible(&fibctx->wait_sem) < 0) { status = -EINTR; @@ -523,7 +536,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) default: data_dir = DMA_NONE; } - if (user_srbcmd->sg.count > (sizeof(sg_list)/sizeof(sg_list[0]))) { + if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) { dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n", le32_to_cpu(srbcmd->sg.count))); rcode = -EINVAL; @@ -609,7 +622,13 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); if(actual_fibsize != fibsize){ // User made a mistake - should not continue - dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); + dprintk((KERN_DEBUG"aacraid: Bad Size specified in " + "Raw SRB command calculated fibsize=%d " + "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " + "issued fibsize=%d\n", + actual_fibsize, user_srbcmd->sg.count, + sizeof(struct aac_srb), sizeof(struct sgentry), + fibsize)); rcode = -EINVAL; goto cleanup; } @@ -651,6 +670,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) psg->count = cpu_to_le32(sg_indx+1); status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); } + if (status == -EINTR) { + rcode = -EINTR; + goto cleanup; + } if (status != 0){ dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); @@ -684,8 +707,10 @@ cleanup: for(i=0; i <= sg_indx; i++){ kfree(sg_list[i]); } - aac_fib_complete(srbfib); - aac_fib_free(srbfib); + if (rcode != -EINTR) { + aac_fib_complete(srbfib); + aac_fib_free(srbfib); + } return rcode; }