vserver 2.0 rc7
[linux-2.6.git] / drivers / scsi / aacraid / commctrl.c
1 /*
2  *      Adaptec AAC series RAID controller driver
3  *      (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
4  *
5  * based on the old aacraid driver that is..
6  * Adaptec aacraid device driver for Linux.
7  *
8  * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; see the file COPYING.  If not, write to
22  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  * Module Name:
25  *  commctrl.c
26  *
27  * Abstract: Contains all routines for control of the AFA comm layer
28  *
29  */
30
31 #include <linux/kernel.h>
32 #include <linux/init.h>
33 #include <linux/types.h>
34 #include <linux/sched.h>
35 #include <linux/pci.h>
36 #include <linux/spinlock.h>
37 #include <linux/slab.h>
38 #include <linux/completion.h>
39 #include <linux/dma-mapping.h>
40 #include <linux/blkdev.h>
41 #include <asm/semaphore.h>
42 #include <asm/uaccess.h>
43
44 #include "aacraid.h"
45
46 /**
47  *      ioctl_send_fib  -       send a FIB from userspace
48  *      @dev:   adapter is being processed
49  *      @arg:   arguments to the ioctl call
50  *      
51  *      This routine sends a fib to the adapter on behalf of a user level
52  *      program.
53  */
54  
55 static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
56 {
57         struct hw_fib * kfib;
58         struct fib *fibptr;
59
60         fibptr = fib_alloc(dev);
61         if(fibptr == NULL)
62                 return -ENOMEM;
63                 
64         kfib = fibptr->hw_fib;
65         /*
66          *      First copy in the header so that we can check the size field.
67          */
68         if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {
69                 fib_free(fibptr);
70                 return -EFAULT;
71         }
72         /*
73          *      Since we copy based on the fib header size, make sure that we
74          *      will not overrun the buffer when we copy the memory. Return
75          *      an error if we would.
76          */
77         if (le16_to_cpu(kfib->header.Size) > 
78                         sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) {
79                 fib_free(fibptr);
80                 return -EINVAL;
81         }
82
83         if (copy_from_user(kfib, arg, le16_to_cpu(kfib->header.Size) +
84                                 sizeof(struct aac_fibhdr))) {
85                 fib_free(fibptr);
86                 return -EFAULT;
87         }
88
89         if (kfib->header.Command == cpu_to_le32(TakeABreakPt)) {
90                 aac_adapter_interrupt(dev);
91                 /*
92                  * Since we didn't really send a fib, zero out the state to allow 
93                  * cleanup code not to assert.
94                  */
95                 kfib->header.XferState = 0;
96         } else {
97                 int retval = fib_send(kfib->header.Command, fibptr,
98                                 le16_to_cpu(kfib->header.Size) , FsaNormal,
99                                 1, 1, NULL, NULL);
100                 if (retval) {
101                         fib_free(fibptr);
102                         return retval;
103                 }
104                 if (fib_complete(fibptr) != 0) {
105                         fib_free(fibptr);
106                         return -EINVAL;
107                 }
108         }
109         /*
110          *      Make sure that the size returned by the adapter (which includes
111          *      the header) is less than or equal to the size of a fib, so we
112          *      don't corrupt application data. Then copy that size to the user
113          *      buffer. (Don't try to add the header information again, since it
114          *      was already included by the adapter.)
115          */
116
117         if (copy_to_user(arg, (void *)kfib, kfib->header.Size)) {
118                 fib_free(fibptr);
119                 return -EFAULT;
120         }
121         fib_free(fibptr);
122         return 0;
123 }
124
125 /**
126  *      open_getadapter_fib     -       Get the next fib
127  *
128  *      This routine will get the next Fib, if available, from the AdapterFibContext
129  *      passed in from the user.
130  */
131
132 static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
133 {
134         struct aac_fib_context * fibctx;
135         int status;
136
137         fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
138         if (fibctx == NULL) {
139                 status = -ENOMEM;
140         } else {
141                 unsigned long flags;
142                 struct list_head * entry;
143                 struct aac_fib_context * context;
144
145                 fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
146                 fibctx->size = sizeof(struct aac_fib_context);
147                 /*
148                  *      Yes yes, I know this could be an index, but we have a
149                  * better guarantee of uniqueness for the locked loop below.
150                  * Without the aid of a persistent history, this also helps
151                  * reduce the chance that the opaque context would be reused.
152                  */
153                 fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
154                 /*
155                  *      Initialize the mutex used to wait for the next AIF.
156                  */
157                 init_MUTEX_LOCKED(&fibctx->wait_sem);
158                 fibctx->wait = 0;
159                 /*
160                  *      Initialize the fibs and set the count of fibs on
161                  *      the list to 0.
162                  */
163                 fibctx->count = 0;
164                 INIT_LIST_HEAD(&fibctx->fib_list);
165                 fibctx->jiffies = jiffies/HZ;
166                 /*
167                  *      Now add this context onto the adapter's 
168                  *      AdapterFibContext list.
169                  */
170                 spin_lock_irqsave(&dev->fib_lock, flags);
171                 /* Ensure that we have a unique identifier */
172                 entry = dev->fib_list.next;
173                 while (entry != &dev->fib_list) {
174                         context = list_entry(entry, struct aac_fib_context, next);
175                         if (context->unique == fibctx->unique) {
176                                 /* Not unique (32 bits) */
177                                 fibctx->unique++;
178                                 entry = dev->fib_list.next;
179                         } else {
180                                 entry = entry->next;
181                         }
182                 }
183                 list_add_tail(&fibctx->next, &dev->fib_list);
184                 spin_unlock_irqrestore(&dev->fib_lock, flags);
185                 if (copy_to_user(arg,  &fibctx->unique, 
186                                                 sizeof(fibctx->unique))) {
187                         status = -EFAULT;
188                 } else {
189                         status = 0;
190                 }       
191         }
192         return status;
193 }
194
195 /**
196  *      next_getadapter_fib     -       get the next fib
197  *      @dev: adapter to use
198  *      @arg: ioctl argument
199  *      
200  *      This routine will get the next Fib, if available, from the AdapterFibContext
201  *      passed in from the user.
202  */
203
204 static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
205 {
206         struct fib_ioctl f;
207         struct fib *fib;
208         struct aac_fib_context *fibctx;
209         int status;
210         struct list_head * entry;
211         unsigned long flags;
212         
213         if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
214                 return -EFAULT;
215         /*
216          *      Verify that the HANDLE passed in was a valid AdapterFibContext
217          *
218          *      Search the list of AdapterFibContext addresses on the adapter
219          *      to be sure this is a valid address
220          */
221         entry = dev->fib_list.next;
222         fibctx = NULL;
223
224         while (entry != &dev->fib_list) {
225                 fibctx = list_entry(entry, struct aac_fib_context, next);
226                 /*
227                  *      Extract the AdapterFibContext from the Input parameters.
228                  */
229                 if (fibctx->unique == f.fibctx) {   /* We found a winner */
230                         break;
231                 }
232                 entry = entry->next;
233                 fibctx = NULL;
234         }
235         if (!fibctx) {
236                 dprintk ((KERN_INFO "Fib Context not found\n"));
237                 return -EINVAL;
238         }
239
240         if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
241                  (fibctx->size != sizeof(struct aac_fib_context))) {
242                 dprintk ((KERN_INFO "Fib Context corrupt?\n"));
243                 return -EINVAL;
244         }
245         status = 0;
246         spin_lock_irqsave(&dev->fib_lock, flags);
247         /*
248          *      If there are no fibs to send back, then either wait or return
249          *      -EAGAIN
250          */
251 return_fib:
252         if (!list_empty(&fibctx->fib_list)) {
253                 struct list_head * entry;
254                 /*
255                  *      Pull the next fib from the fibs
256                  */
257                 entry = fibctx->fib_list.next;
258                 list_del(entry);
259                 
260                 fib = list_entry(entry, struct fib, fiblink);
261                 fibctx->count--;
262                 spin_unlock_irqrestore(&dev->fib_lock, flags);
263                 if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) {
264                         kfree(fib->hw_fib);
265                         kfree(fib);
266                         return -EFAULT;
267                 }       
268                 /*
269                  *      Free the space occupied by this copy of the fib.
270                  */
271                 kfree(fib->hw_fib);
272                 kfree(fib);
273                 status = 0;
274                 fibctx->jiffies = jiffies/HZ;
275         } else {
276                 spin_unlock_irqrestore(&dev->fib_lock, flags);
277                 if (f.wait) {
278                         if(down_interruptible(&fibctx->wait_sem) < 0) {
279                                 status = -EINTR;
280                         } else {
281                                 /* Lock again and retry */
282                                 spin_lock_irqsave(&dev->fib_lock, flags);
283                                 goto return_fib;
284                         }
285                 } else {
286                         status = -EAGAIN;
287                 }       
288         }
289         return status;
290 }
291
292 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
293 {
294         struct fib *fib;
295
296         /*
297          *      First free any FIBs that have not been consumed.
298          */
299         while (!list_empty(&fibctx->fib_list)) {
300                 struct list_head * entry;
301                 /*
302                  *      Pull the next fib from the fibs
303                  */
304                 entry = fibctx->fib_list.next;
305                 list_del(entry);
306                 fib = list_entry(entry, struct fib, fiblink);
307                 fibctx->count--;
308                 /*
309                  *      Free the space occupied by this copy of the fib.
310                  */
311                 kfree(fib->hw_fib);
312                 kfree(fib);
313         }
314         /*
315          *      Remove the Context from the AdapterFibContext List
316          */
317         list_del(&fibctx->next);
318         /*
319          *      Invalidate context
320          */
321         fibctx->type = 0;
322         /*
323          *      Free the space occupied by the Context
324          */
325         kfree(fibctx);
326         return 0;
327 }
328
329 /**
330  *      close_getadapter_fib    -       close down user fib context
331  *      @dev: adapter
332  *      @arg: ioctl arguments
333  *
334  *      This routine will close down the fibctx passed in from the user.
335  */
336  
337 static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
338 {
339         struct aac_fib_context *fibctx;
340         int status;
341         unsigned long flags;
342         struct list_head * entry;
343
344         /*
345          *      Verify that the HANDLE passed in was a valid AdapterFibContext
346          *
347          *      Search the list of AdapterFibContext addresses on the adapter
348          *      to be sure this is a valid address
349          */
350
351         entry = dev->fib_list.next;
352         fibctx = NULL;
353
354         while(entry != &dev->fib_list) {
355                 fibctx = list_entry(entry, struct aac_fib_context, next);
356                 /*
357                  *      Extract the fibctx from the input parameters
358                  */
359                 if (fibctx->unique == (u32)(unsigned long)arg) {   
360                         /* We found a winner */
361                         break;
362                 }
363                 entry = entry->next;
364                 fibctx = NULL;
365         }
366
367         if (!fibctx)
368                 return 0; /* Already gone */
369
370         if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
371                  (fibctx->size != sizeof(struct aac_fib_context)))
372                 return -EINVAL;
373         spin_lock_irqsave(&dev->fib_lock, flags);
374         status = aac_close_fib_context(dev, fibctx);
375         spin_unlock_irqrestore(&dev->fib_lock, flags);
376         return status;
377 }
378
379 /**
380  *      check_revision  -       close down user fib context
381  *      @dev: adapter
382  *      @arg: ioctl arguments
383  *
384  *      This routine returns the driver version.
385  *      Under Linux, there have been no version incompatibilities, so this is 
386  *      simple!
387  */
388
389 static int check_revision(struct aac_dev *dev, void __user *arg)
390 {
391         struct revision response;
392
393         response.compat = 1;
394         response.version = dev->adapter_info.kernelrev;
395         response.build = dev->adapter_info.kernelbuild;
396
397         if (copy_to_user(arg, &response, sizeof(response)))
398                 return -EFAULT;
399         return 0;
400 }
401
402 /**
403  *
404  * aac_send_raw_scb
405  *
406  */
407
408 int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
409 {
410         struct fib* srbfib;
411         int status;
412         struct aac_srb *srbcmd;
413         struct aac_srb __user *user_srb = arg;
414         struct aac_srb_reply __user *user_reply;
415         struct aac_srb_reply* reply;
416         u32 fibsize = 0;
417         u32 flags = 0;
418         s32 rcode = 0;
419         u32 data_dir;
420         void __user *sg_user[32];
421         void *sg_list[32];
422         u32   sg_indx = 0;
423         u32 byte_count = 0;
424         u32 actual_fibsize = 0;
425         int i;
426
427
428         if (!capable(CAP_SYS_ADMIN)){
429                 printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); 
430                 return -EPERM;
431         }
432         /*
433          *      Allocate and initialize a Fib then setup a BlockWrite command
434          */
435         if (!(srbfib = fib_alloc(dev))) {
436                 return -1;
437         }
438         fib_init(srbfib);
439
440         srbcmd = (struct aac_srb*) fib_data(srbfib);
441
442         if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
443                 printk(KERN_DEBUG"aacraid: Could not copy data size from user\n"); 
444                 rcode = -EFAULT;
445                 goto cleanup;
446         }
447
448         if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
449                 rcode = -EINVAL;
450                 goto cleanup;
451         }
452
453         if(copy_from_user(srbcmd, user_srb,fibsize)){
454                 printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); 
455                 rcode = -EFAULT;
456                 goto cleanup;
457         }
458
459         user_reply = arg+fibsize;
460
461         flags = srbcmd->flags;
462         // Fix up srb for endian and force some values
463         srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);       // Force this
464         srbcmd->channel  = cpu_to_le32(srbcmd->channel);
465         srbcmd->id       = cpu_to_le32(srbcmd->id);
466         srbcmd->lun      = cpu_to_le32(srbcmd->lun);
467         srbcmd->flags    = cpu_to_le32(srbcmd->flags);
468         srbcmd->timeout  = cpu_to_le32(srbcmd->timeout);
469         srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
470         srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
471         
472         switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
473         case SRB_DataOut:
474                 data_dir = DMA_TO_DEVICE;
475                 break;
476         case (SRB_DataIn | SRB_DataOut):
477                 data_dir = DMA_BIDIRECTIONAL;
478                 break;
479         case SRB_DataIn:
480                 data_dir = DMA_FROM_DEVICE;
481                 break;
482         default:
483                 data_dir = DMA_NONE;
484         }
485         if (dev->dac_support == 1) {
486                 struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
487                 byte_count = 0;
488
489                 /*
490                  * This should also catch if user used the 32 bit sgmap
491                  */
492                 actual_fibsize = sizeof(struct aac_srb) - 
493                         sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * 
494                                 sizeof(struct sgentry64));
495                 if(actual_fibsize != fibsize){ // User made a mistake - should not continue
496                         printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
497                         rcode = -EINVAL;
498                         goto cleanup;
499                 }
500                 if ((data_dir == DMA_NONE) && psg->count) { 
501                         printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
502                         rcode = -EINVAL;
503                         goto cleanup;
504                 }
505
506                 for (i = 0; i < psg->count; i++) {
507                         dma_addr_t addr; 
508                         u64 le_addr;
509                         void* p;
510                         p = kmalloc(psg->sg[i].count,GFP_KERNEL|__GFP_DMA);
511                         if(p == 0) {
512                                 printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
513                                 psg->sg[i].count,i,psg->count);
514                                 rcode = -ENOMEM;
515                                 goto cleanup;
516                         }
517                         sg_user[i] = (void __user *)psg->sg[i].addr;
518                         sg_list[i] = p; // save so we can clean up later
519                         sg_indx = i;
520
521                         if( flags & SRB_DataOut ){
522                                 if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
523                                         printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); 
524                                         rcode = -EFAULT;
525                                         goto cleanup;
526                                 }
527                         }
528                         addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
529
530                         le_addr = cpu_to_le64(addr);
531                         psg->sg[i].addr[1] = (u32)(le_addr>>32);
532                         psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
533                         psg->sg[i].count = cpu_to_le32(psg->sg[i].count);  
534                         byte_count += psg->sg[i].count;
535                 }
536
537                 srbcmd->count = cpu_to_le32(byte_count);
538                 status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
539         } else {
540                 struct sgmap* psg = &srbcmd->sg;
541                 byte_count = 0;
542
543                 actual_fibsize = sizeof (struct aac_srb) + 
544                         (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * 
545                          sizeof (struct sgentry));
546                 if(actual_fibsize != fibsize){ // User made a mistake - should not continue
547                         printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
548                         rcode = -EINVAL;
549                         goto cleanup;
550                 }
551                 if ((data_dir == DMA_NONE) && psg->count) {
552                         printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
553                         rcode = -EINVAL;
554                         goto cleanup;
555                 }
556                 for (i = 0; i < psg->count; i++) {
557                         dma_addr_t addr; 
558                         void* p;
559                         p = kmalloc(psg->sg[i].count,GFP_KERNEL);
560                         if(p == 0) {
561                                 printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
562                                 psg->sg[i].count,i,psg->count);
563                                 rcode = -ENOMEM;
564                                 goto cleanup;
565                         }
566                         sg_user[i] = (void __user *)(psg->sg[i].addr);
567                         sg_list[i] = p; // save so we can clean up later
568                         sg_indx = i;
569
570                         if( flags & SRB_DataOut ){
571                                 if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
572                                         printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); 
573                                         rcode = -EFAULT;
574                                         goto cleanup;
575                                 }
576                         }
577                         addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
578
579                         psg->sg[i].addr = cpu_to_le32(addr);
580                         psg->sg[i].count = cpu_to_le32(psg->sg[i].count);  
581                         byte_count += psg->sg[i].count;
582                 }
583                 srbcmd->count = cpu_to_le32(byte_count);
584                 status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
585         }
586
587         if (status != 0){
588                 printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"); 
589                 rcode = -1;
590                 goto cleanup;
591         }
592
593         if( flags & SRB_DataIn ) {
594                 for(i = 0 ; i <= sg_indx; i++){
595                         if(copy_to_user(sg_user[i],sg_list[i],le32_to_cpu(srbcmd->sg.sg[i].count))){
596                                 printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n"); 
597                                 rcode = -EFAULT;
598                                 goto cleanup;
599
600                         }
601                 }
602         }
603
604         reply = (struct aac_srb_reply *) fib_data(srbfib);
605         if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){
606                 printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); 
607                 rcode = -EFAULT;
608                 goto cleanup;
609         }
610
611 cleanup:
612         for(i=0; i <= sg_indx; i++){
613                 kfree(sg_list[i]);
614         }
615         fib_complete(srbfib);
616         fib_free(srbfib);
617
618         return rcode;
619 }
620
621
622 struct aac_pci_info {
623         u32 bus;
624         u32 slot;
625 };
626
627
628 int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
629 {
630         struct aac_pci_info pci_info;
631
632         pci_info.bus = dev->pdev->bus->number;
633         pci_info.slot = PCI_SLOT(dev->pdev->devfn);
634
635        if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
636                 printk(KERN_DEBUG "aacraid: Could not copy pci info\n");
637                return -EFAULT;
638         }
639         return 0;
640  }
641  
642
643 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
644 {
645         int status;
646         
647         /*
648          *      HBA gets first crack
649          */
650          
651         status = aac_dev_ioctl(dev, cmd, arg);
652         if(status != -ENOTTY)
653                 return status;
654
655         switch (cmd) {
656         case FSACTL_MINIPORT_REV_CHECK:
657                 status = check_revision(dev, arg);
658                 break;
659         case FSACTL_SENDFIB:
660                 status = ioctl_send_fib(dev, arg);
661                 break;
662         case FSACTL_OPEN_GET_ADAPTER_FIB:
663                 status = open_getadapter_fib(dev, arg);
664                 break;
665         case FSACTL_GET_NEXT_ADAPTER_FIB:
666                 status = next_getadapter_fib(dev, arg);
667                 break;
668         case FSACTL_CLOSE_GET_ADAPTER_FIB:
669                 status = close_getadapter_fib(dev, arg);
670                 break;
671         case FSACTL_SEND_RAW_SRB:
672                 status = aac_send_raw_srb(dev,arg);
673                 break;
674         case FSACTL_GET_PCI_INFO:
675                 status = aac_get_pci_info(dev,arg);
676                 break;
677         default:
678                 status = -ENOTTY;
679                 break;  
680         }
681         return status;
682 }
683