rk_fiq_debugger: map signal irq for fiq mode
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / aacraid / commctrl.c
index 1ef041bc60c89c17b9f130124e9e1273995adb11..f78cc943d230eb251c88e275f939cbd5fd6943f2 100644 (file)
@@ -63,7 +63,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
        struct fib *fibptr;
        struct hw_fib * hw_fib = (struct hw_fib *)0;
        dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
-       unsigned size;
+       unsigned int size, osize;
        int retval;
 
        if (dev->in_reset) {
@@ -87,7 +87,8 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
         *      will not overrun the buffer when we copy the memory. Return
         *      an error if we would.
         */
-       size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr);
+       osize = size = le16_to_cpu(kfib->header.Size) +
+               sizeof(struct aac_fibhdr);
        if (size < le16_to_cpu(kfib->header.SenderSize))
                size = le16_to_cpu(kfib->header.SenderSize);
        if (size > dev->max_fib_size) {
@@ -118,6 +119,14 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
                goto cleanup;
        }
 
+       /* Sanity check the second copy */
+       if ((osize != le16_to_cpu(kfib->header.Size) +
+               sizeof(struct aac_fibhdr))
+               || (size < le16_to_cpu(kfib->header.SenderSize))) {
+               retval = -EINVAL;
+               goto cleanup;
+       }
+
        if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
                aac_adapter_interrupt(dev);
                /*
@@ -318,7 +327,8 @@ return_fib:
                        kthread_stop(dev->thread);
                        ssleep(1);
                        dev->aif_thread = 0;
-                       dev->thread = kthread_run(aac_command_thread, dev, dev->name);
+                       dev->thread = kthread_run(aac_command_thread, dev,
+                                                 "%s", dev->name);
                        ssleep(1);
                }
                if (f.wait) {
@@ -510,7 +520,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                goto cleanup;
        }
 
-       if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) {
+       if ((fibsize < (sizeof(struct user_aac_srb) - sizeof(struct user_sgentry))) ||
+           (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))) {
                rcode = -EINVAL;
                goto cleanup;
        }
@@ -687,7 +698,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                        kfree (usg);
                }
                srbcmd->count = cpu_to_le32(byte_count);
-               psg->count = cpu_to_le32(sg_indx+1);
+               if (user_srbcmd->sg.count)
+                       psg->count = cpu_to_le32(sg_indx+1);
+               else
+                       psg->count = 0;
                status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
        } else {
                struct user_sgmap* upsg = &user_srbcmd->sg;
@@ -773,7 +787,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                        }
                }
                srbcmd->count = cpu_to_le32(byte_count);
-               psg->count = cpu_to_le32(sg_indx+1);
+               if (user_srbcmd->sg.count)
+                       psg->count = cpu_to_le32(sg_indx+1);
+               else
+                       psg->count = 0;
                status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
        }
        if (status == -ERESTARTSYS) {