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-2007 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/pci.h> 35 #include <linux/spinlock.h> 36 #include <linux/slab.h> 37 #include <linux/completion.h> 38 #include <linux/dma-mapping.h> 39 #include <linux/blkdev.h> 40 #include <linux/delay.h> /* ssleep prototype */ 41 #include <linux/kthread.h> 42 #include <asm/semaphore.h> 43 #include <asm/uaccess.h> 44 45 #include "aacraid.h" 46 47 /** 48 * ioctl_send_fib - send a FIB from userspace 49 * @dev: adapter is being processed 50 * @arg: arguments to the ioctl call 51 * 52 * This routine sends a fib to the adapter on behalf of a user level 53 * program. 54 */ 55 # define AAC_DEBUG_PREAMBLE KERN_INFO 56 # define AAC_DEBUG_POSTAMBLE 57 58 static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) 59 { 60 struct hw_fib * kfib; 61 struct fib *fibptr; 62 struct hw_fib * hw_fib = (struct hw_fib *)0; 63 dma_addr_t hw_fib_pa = (dma_addr_t)0LL; 64 unsigned size; 65 int retval; 66 67 if (dev->in_reset) { 68 return -EBUSY; 69 } 70 fibptr = aac_fib_alloc(dev); 71 if(fibptr == NULL) { 72 return -ENOMEM; 73 } 74 75 kfib = fibptr->hw_fib_va; 76 /* 77 * First copy in the header so that we can check the size field. 78 */ 79 if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) { 80 aac_fib_free(fibptr); 81 return -EFAULT; 82 } 83 /* 84 * Since we copy based on the fib header size, make sure that we 85 * will not overrun the buffer when we copy the memory. Return 86 * an error if we would. 87 */ 88 size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr); 89 if (size < le16_to_cpu(kfib->header.SenderSize)) 90 size = le16_to_cpu(kfib->header.SenderSize); 91 if (size > dev->max_fib_size) { 92 if (size > 2048) { 93 retval = -EINVAL; 94 goto cleanup; 95 } 96 /* Highjack the hw_fib */ 97 hw_fib = fibptr->hw_fib_va; 98 hw_fib_pa = fibptr->hw_fib_pa; 99 fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); 100 memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); 101 memcpy(kfib, hw_fib, dev->max_fib_size); 102 } 103 104 if (copy_from_user(kfib, arg, size)) { 105 retval = -EFAULT; 106 goto cleanup; 107 } 108 109 if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) { 110 aac_adapter_interrupt(dev); 111 /* 112 * Since we didn't really send a fib, zero out the state to allow 113 * cleanup code not to assert. 114 */ 115 kfib->header.XferState = 0; 116 } else { 117 retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr, 118 le16_to_cpu(kfib->header.Size) , FsaNormal, 119 1, 1, NULL, NULL); 120 if (retval) { 121 goto cleanup; 122 } 123 if (aac_fib_complete(fibptr) != 0) { 124 retval = -EINVAL; 125 goto cleanup; 126 } 127 } 128 /* 129 * Make sure that the size returned by the adapter (which includes 130 * the header) is less than or equal to the size of a fib, so we 131 * don't corrupt application data. Then copy that size to the user 132 * buffer. (Don't try to add the header information again, since it 133 * was already included by the adapter.) 134 */ 135 136 retval = 0; 137 if (copy_to_user(arg, (void *)kfib, size)) 138 retval = -EFAULT; 139 cleanup: 140 if (hw_fib) { 141 pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); 142 fibptr->hw_fib_pa = hw_fib_pa; 143 fibptr->hw_fib_va = hw_fib; 144 } 145 if (retval != -EINTR) 146 aac_fib_free(fibptr); 147 return retval; 148 } 149 150 /** 151 * open_getadapter_fib - Get the next fib 152 * 153 * This routine will get the next Fib, if available, from the AdapterFibContext 154 * passed in from the user. 155 */ 156 157 static int open_getadapter_fib(struct aac_dev * dev, void __user *arg) 158 { 159 struct aac_fib_context * fibctx; 160 int status; 161 162 fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL); 163 if (fibctx == NULL) { 164 status = -ENOMEM; 165 } else { 166 unsigned long flags; 167 struct list_head * entry; 168 struct aac_fib_context * context; 169 170 fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT; 171 fibctx->size = sizeof(struct aac_fib_context); 172 /* 173 * Yes yes, I know this could be an index, but we have a 174 * better guarantee of uniqueness for the locked loop below. 175 * Without the aid of a persistent history, this also helps 176 * reduce the chance that the opaque context would be reused. 177 */ 178 fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF); 179 /* 180 * Initialize the mutex used to wait for the next AIF. 181 */ 182 init_MUTEX_LOCKED(&fibctx->wait_sem); 183 fibctx->wait = 0; 184 /* 185 * Initialize the fibs and set the count of fibs on 186 * the list to 0. 187 */ 188 fibctx->count = 0; 189 INIT_LIST_HEAD(&fibctx->fib_list); 190 fibctx->jiffies = jiffies/HZ; 191 /* 192 * Now add this context onto the adapter's 193 * AdapterFibContext list. 194 */ 195 spin_lock_irqsave(&dev->fib_lock, flags); 196 /* Ensure that we have a unique identifier */ 197 entry = dev->fib_list.next; 198 while (entry != &dev->fib_list) { 199 context = list_entry(entry, struct aac_fib_context, next); 200 if (context->unique == fibctx->unique) { 201 /* Not unique (32 bits) */ 202 fibctx->unique++; 203 entry = dev->fib_list.next; 204 } else { 205 entry = entry->next; 206 } 207 } 208 list_add_tail(&fibctx->next, &dev->fib_list); 209 spin_unlock_irqrestore(&dev->fib_lock, flags); 210 if (copy_to_user(arg, &fibctx->unique, 211 sizeof(fibctx->unique))) { 212 status = -EFAULT; 213 } else { 214 status = 0; 215 } 216 } 217 return status; 218 } 219 220 /** 221 * next_getadapter_fib - get the next fib 222 * @dev: adapter to use 223 * @arg: ioctl argument 224 * 225 * This routine will get the next Fib, if available, from the AdapterFibContext 226 * passed in from the user. 227 */ 228 229 static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) 230 { 231 struct fib_ioctl f; 232 struct fib *fib; 233 struct aac_fib_context *fibctx; 234 int status; 235 struct list_head * entry; 236 unsigned long flags; 237 238 if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl))) 239 return -EFAULT; 240 /* 241 * Verify that the HANDLE passed in was a valid AdapterFibContext 242 * 243 * Search the list of AdapterFibContext addresses on the adapter 244 * to be sure this is a valid address 245 */ 246 spin_lock_irqsave(&dev->fib_lock, flags); 247 entry = dev->fib_list.next; 248 fibctx = NULL; 249 250 while (entry != &dev->fib_list) { 251 fibctx = list_entry(entry, struct aac_fib_context, next); 252 /* 253 * Extract the AdapterFibContext from the Input parameters. 254 */ 255 if (fibctx->unique == f.fibctx) { /* We found a winner */ 256 break; 257 } 258 entry = entry->next; 259 fibctx = NULL; 260 } 261 if (!fibctx) { 262 spin_unlock_irqrestore(&dev->fib_lock, flags); 263 dprintk ((KERN_INFO "Fib Context not found\n")); 264 return -EINVAL; 265 } 266 267 if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || 268 (fibctx->size != sizeof(struct aac_fib_context))) { 269 spin_unlock_irqrestore(&dev->fib_lock, flags); 270 dprintk ((KERN_INFO "Fib Context corrupt?\n")); 271 return -EINVAL; 272 } 273 status = 0; 274 /* 275 * If there are no fibs to send back, then either wait or return 276 * -EAGAIN 277 */ 278 return_fib: 279 if (!list_empty(&fibctx->fib_list)) { 280 /* 281 * Pull the next fib from the fibs 282 */ 283 entry = fibctx->fib_list.next; 284 list_del(entry); 285 286 fib = list_entry(entry, struct fib, fiblink); 287 fibctx->count--; 288 spin_unlock_irqrestore(&dev->fib_lock, flags); 289 if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) { 290 kfree(fib->hw_fib_va); 291 kfree(fib); 292 return -EFAULT; 293 } 294 /* 295 * Free the space occupied by this copy of the fib. 296 */ 297 kfree(fib->hw_fib_va); 298 kfree(fib); 299 status = 0; 300 } else { 301 spin_unlock_irqrestore(&dev->fib_lock, flags); 302 /* If someone killed the AIF aacraid thread, restart it */ 303 status = !dev->aif_thread; 304 if (status && !dev->in_reset && dev->queues && dev->fsa_dev) { 305 /* Be paranoid, be very paranoid! */ 306 kthread_stop(dev->thread); 307 ssleep(1); 308 dev->aif_thread = 0; 309 dev->thread = kthread_run(aac_command_thread, dev, dev->name); 310 ssleep(1); 311 } 312 if (f.wait) { 313 if(down_interruptible(&fibctx->wait_sem) < 0) { 314 status = -EINTR; 315 } else { 316 /* Lock again and retry */ 317 spin_lock_irqsave(&dev->fib_lock, flags); 318 goto return_fib; 319 } 320 } else { 321 status = -EAGAIN; 322 } 323 } 324 fibctx->jiffies = jiffies/HZ; 325 return status; 326 } 327 328 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) 329 { 330 struct fib *fib; 331 unsigned long flags; 332 333 spin_lock_irqsave(&dev->fib_lock, flags); 334 /* 335 * First free any FIBs that have not been consumed. 336 */ 337 while (!list_empty(&fibctx->fib_list)) { 338 struct list_head * entry; 339 /* 340 * Pull the next fib from the fibs 341 */ 342 entry = fibctx->fib_list.next; 343 list_del(entry); 344 fib = list_entry(entry, struct fib, fiblink); 345 fibctx->count--; 346 /* 347 * Free the space occupied by this copy of the fib. 348 */ 349 kfree(fib->hw_fib_va); 350 kfree(fib); 351 } 352 /* 353 * Remove the Context from the AdapterFibContext List 354 */ 355 list_del(&fibctx->next); 356 spin_unlock_irqrestore(&dev->fib_lock, flags); 357 /* 358 * Invalidate context 359 */ 360 fibctx->type = 0; 361 /* 362 * Free the space occupied by the Context 363 */ 364 kfree(fibctx); 365 return 0; 366 } 367 368 /** 369 * close_getadapter_fib - close down user fib context 370 * @dev: adapter 371 * @arg: ioctl arguments 372 * 373 * This routine will close down the fibctx passed in from the user. 374 */ 375 376 static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) 377 { 378 struct aac_fib_context *fibctx; 379 int status; 380 unsigned long flags; 381 struct list_head * entry; 382 383 /* 384 * Verify that the HANDLE passed in was a valid AdapterFibContext 385 * 386 * Search the list of AdapterFibContext addresses on the adapter 387 * to be sure this is a valid address 388 */ 389 390 entry = dev->fib_list.next; 391 fibctx = NULL; 392 393 while(entry != &dev->fib_list) { 394 fibctx = list_entry(entry, struct aac_fib_context, next); 395 /* 396 * Extract the fibctx from the input parameters 397 */ 398 if (fibctx->unique == (u32)(uintptr_t)arg) /* We found a winner */ 399 break; 400 entry = entry->next; 401 fibctx = NULL; 402 } 403 404 if (!fibctx) 405 return 0; /* Already gone */ 406 407 if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) || 408 (fibctx->size != sizeof(struct aac_fib_context))) 409 return -EINVAL; 410 spin_lock_irqsave(&dev->fib_lock, flags); 411 status = aac_close_fib_context(dev, fibctx); 412 spin_unlock_irqrestore(&dev->fib_lock, flags); 413 return status; 414 } 415 416 /** 417 * check_revision - close down user fib context 418 * @dev: adapter 419 * @arg: ioctl arguments 420 * 421 * This routine returns the driver version. 422 * Under Linux, there have been no version incompatibilities, so this is 423 * simple! 424 */ 425 426 static int check_revision(struct aac_dev *dev, void __user *arg) 427 { 428 struct revision response; 429 char *driver_version = aac_driver_version; 430 u32 version; 431 432 response.compat = 1; 433 version = (simple_strtol(driver_version, 434 &driver_version, 10) << 24) | 0x00000400; 435 version += simple_strtol(driver_version + 1, &driver_version, 10) << 16; 436 version += simple_strtol(driver_version + 1, NULL, 10); 437 response.version = cpu_to_le32(version); 438 # ifdef AAC_DRIVER_BUILD 439 response.build = cpu_to_le32(AAC_DRIVER_BUILD); 440 # else 441 response.build = cpu_to_le32(9999); 442 # endif 443 444 if (copy_to_user(arg, &response, sizeof(response))) 445 return -EFAULT; 446 return 0; 447 } 448 449 450 /** 451 * 452 * aac_send_raw_scb 453 * 454 */ 455 456 static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) 457 { 458 struct fib* srbfib; 459 int status; 460 struct aac_srb *srbcmd = NULL; 461 struct user_aac_srb *user_srbcmd = NULL; 462 struct user_aac_srb __user *user_srb = arg; 463 struct aac_srb_reply __user *user_reply; 464 struct aac_srb_reply* reply; 465 u32 fibsize = 0; 466 u32 flags = 0; 467 s32 rcode = 0; 468 u32 data_dir; 469 void __user *sg_user[32]; 470 void *sg_list[32]; 471 u32 sg_indx = 0; 472 u32 byte_count = 0; 473 u32 actual_fibsize64, actual_fibsize = 0; 474 int i; 475 476 477 if (dev->in_reset) { 478 dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); 479 return -EBUSY; 480 } 481 if (!capable(CAP_SYS_ADMIN)){ 482 dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); 483 return -EPERM; 484 } 485 /* 486 * Allocate and initialize a Fib then setup a SRB command 487 */ 488 if (!(srbfib = aac_fib_alloc(dev))) { 489 return -ENOMEM; 490 } 491 aac_fib_init(srbfib); 492 493 srbcmd = (struct aac_srb*) fib_data(srbfib); 494 495 memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */ 496 if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){ 497 dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n")); 498 rcode = -EFAULT; 499 goto cleanup; 500 } 501 502 if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) { 503 rcode = -EINVAL; 504 goto cleanup; 505 } 506 507 user_srbcmd = kmalloc(fibsize, GFP_KERNEL); 508 if (!user_srbcmd) { 509 dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n")); 510 rcode = -ENOMEM; 511 goto cleanup; 512 } 513 if(copy_from_user(user_srbcmd, user_srb,fibsize)){ 514 dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); 515 rcode = -EFAULT; 516 goto cleanup; 517 } 518 519 user_reply = arg+fibsize; 520 521 flags = user_srbcmd->flags; /* from user in cpu order */ 522 // Fix up srb for endian and force some values 523 524 srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this 525 srbcmd->channel = cpu_to_le32(user_srbcmd->channel); 526 srbcmd->id = cpu_to_le32(user_srbcmd->id); 527 srbcmd->lun = cpu_to_le32(user_srbcmd->lun); 528 srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout); 529 srbcmd->flags = cpu_to_le32(flags); 530 srbcmd->retry_limit = 0; // Obsolete parameter 531 srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size); 532 memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb)); 533 534 switch (flags & (SRB_DataIn | SRB_DataOut)) { 535 case SRB_DataOut: 536 data_dir = DMA_TO_DEVICE; 537 break; 538 case (SRB_DataIn | SRB_DataOut): 539 data_dir = DMA_BIDIRECTIONAL; 540 break; 541 case SRB_DataIn: 542 data_dir = DMA_FROM_DEVICE; 543 break; 544 default: 545 data_dir = DMA_NONE; 546 } 547 if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) { 548 dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n", 549 le32_to_cpu(srbcmd->sg.count))); 550 rcode = -EINVAL; 551 goto cleanup; 552 } 553 actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + 554 ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry)); 555 actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) * 556 (sizeof(struct sgentry64) - sizeof(struct sgentry)); 557 /* User made a mistake - should not continue */ 558 if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) { 559 dprintk((KERN_DEBUG"aacraid: Bad Size specified in " 560 "Raw SRB command calculated fibsize=%lu;%lu " 561 "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu " 562 "issued fibsize=%d\n", 563 actual_fibsize, actual_fibsize64, user_srbcmd->sg.count, 564 sizeof(struct aac_srb), sizeof(struct sgentry), 565 sizeof(struct sgentry64), fibsize)); 566 rcode = -EINVAL; 567 goto cleanup; 568 } 569 if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) { 570 dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); 571 rcode = -EINVAL; 572 goto cleanup; 573 } 574 byte_count = 0; 575 if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) { 576 struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; 577 struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; 578 579 /* 580 * This should also catch if user used the 32 bit sgmap 581 */ 582 if (actual_fibsize64 == fibsize) { 583 actual_fibsize = actual_fibsize64; 584 for (i = 0; i < upsg->count; i++) { 585 u64 addr; 586 void* p; 587 /* Does this really need to be GFP_DMA? */ 588 p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); 589 if(!p) { 590 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 591 upsg->sg[i].count,i,upsg->count)); 592 rcode = -ENOMEM; 593 goto cleanup; 594 } 595 addr = (u64)upsg->sg[i].addr[0]; 596 addr += ((u64)upsg->sg[i].addr[1]) << 32; 597 sg_user[i] = (void __user *)(uintptr_t)addr; 598 sg_list[i] = p; // save so we can clean up later 599 sg_indx = i; 600 601 if (flags & SRB_DataOut) { 602 if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ 603 dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 604 rcode = -EFAULT; 605 goto cleanup; 606 } 607 } 608 addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); 609 610 psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); 611 psg->sg[i].addr[1] = cpu_to_le32(addr>>32); 612 byte_count += upsg->sg[i].count; 613 psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); 614 } 615 } else { 616 struct user_sgmap* usg; 617 usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) 618 + sizeof(struct sgmap), GFP_KERNEL); 619 if (!usg) { 620 dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); 621 rcode = -ENOMEM; 622 goto cleanup; 623 } 624 memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) 625 + sizeof(struct sgmap)); 626 actual_fibsize = actual_fibsize64; 627 628 for (i = 0; i < usg->count; i++) { 629 u64 addr; 630 void* p; 631 /* Does this really need to be GFP_DMA? */ 632 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); 633 if(!p) { 634 kfree (usg); 635 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 636 usg->sg[i].count,i,usg->count)); 637 rcode = -ENOMEM; 638 goto cleanup; 639 } 640 sg_user[i] = (void __user *)(uintptr_t)usg->sg[i].addr; 641 sg_list[i] = p; // save so we can clean up later 642 sg_indx = i; 643 644 if (flags & SRB_DataOut) { 645 if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ 646 kfree (usg); 647 dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 648 rcode = -EFAULT; 649 goto cleanup; 650 } 651 } 652 addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); 653 654 psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); 655 psg->sg[i].addr[1] = cpu_to_le32(addr>>32); 656 byte_count += usg->sg[i].count; 657 psg->sg[i].count = cpu_to_le32(usg->sg[i].count); 658 } 659 kfree (usg); 660 } 661 srbcmd->count = cpu_to_le32(byte_count); 662 psg->count = cpu_to_le32(sg_indx+1); 663 status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); 664 } else { 665 struct user_sgmap* upsg = &user_srbcmd->sg; 666 struct sgmap* psg = &srbcmd->sg; 667 668 if (actual_fibsize64 == fibsize) { 669 struct user_sgmap64* usg = (struct user_sgmap64 *)upsg; 670 for (i = 0; i < upsg->count; i++) { 671 uintptr_t addr; 672 void* p; 673 /* Does this really need to be GFP_DMA? */ 674 p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); 675 if(!p) { 676 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 677 usg->sg[i].count,i,usg->count)); 678 rcode = -ENOMEM; 679 goto cleanup; 680 } 681 addr = (u64)usg->sg[i].addr[0]; 682 addr += ((u64)usg->sg[i].addr[1]) << 32; 683 sg_user[i] = (void __user *)addr; 684 sg_list[i] = p; // save so we can clean up later 685 sg_indx = i; 686 687 if (flags & SRB_DataOut) { 688 if(copy_from_user(p,sg_user[i],usg->sg[i].count)){ 689 dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 690 rcode = -EFAULT; 691 goto cleanup; 692 } 693 } 694 addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); 695 696 psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); 697 byte_count += usg->sg[i].count; 698 psg->sg[i].count = cpu_to_le32(usg->sg[i].count); 699 } 700 } else { 701 for (i = 0; i < upsg->count; i++) { 702 dma_addr_t addr; 703 void* p; 704 p = kmalloc(upsg->sg[i].count, GFP_KERNEL); 705 if (!p) { 706 dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 707 upsg->sg[i].count, i, upsg->count)); 708 rcode = -ENOMEM; 709 goto cleanup; 710 } 711 sg_user[i] = (void __user *)(uintptr_t)upsg->sg[i].addr; 712 sg_list[i] = p; // save so we can clean up later 713 sg_indx = i; 714 715 if (flags & SRB_DataOut) { 716 if(copy_from_user(p, sg_user[i], 717 upsg->sg[i].count)) { 718 dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 719 rcode = -EFAULT; 720 goto cleanup; 721 } 722 } 723 addr = pci_map_single(dev->pdev, p, 724 upsg->sg[i].count, data_dir); 725 726 psg->sg[i].addr = cpu_to_le32(addr); 727 byte_count += upsg->sg[i].count; 728 psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); 729 } 730 } 731 srbcmd->count = cpu_to_le32(byte_count); 732 psg->count = cpu_to_le32(sg_indx+1); 733 status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); 734 } 735 if (status == -EINTR) { 736 rcode = -EINTR; 737 goto cleanup; 738 } 739 740 if (status != 0){ 741 dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); 742 rcode = -ENXIO; 743 goto cleanup; 744 } 745 746 if (flags & SRB_DataIn) { 747 for(i = 0 ; i <= sg_indx; i++){ 748 byte_count = le32_to_cpu( 749 (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) 750 ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count 751 : srbcmd->sg.sg[i].count); 752 if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ 753 dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n")); 754 rcode = -EFAULT; 755 goto cleanup; 756 757 } 758 } 759 } 760 761 reply = (struct aac_srb_reply *) fib_data(srbfib); 762 if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){ 763 dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n")); 764 rcode = -EFAULT; 765 goto cleanup; 766 } 767 768 cleanup: 769 kfree(user_srbcmd); 770 for(i=0; i <= sg_indx; i++){ 771 kfree(sg_list[i]); 772 } 773 if (rcode != -EINTR) { 774 aac_fib_complete(srbfib); 775 aac_fib_free(srbfib); 776 } 777 778 return rcode; 779 } 780 781 struct aac_pci_info { 782 u32 bus; 783 u32 slot; 784 }; 785 786 787 static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) 788 { 789 struct aac_pci_info pci_info; 790 791 pci_info.bus = dev->pdev->bus->number; 792 pci_info.slot = PCI_SLOT(dev->pdev->devfn); 793 794 if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) { 795 dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n")); 796 return -EFAULT; 797 } 798 return 0; 799 } 800 801 802 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) 803 { 804 int status; 805 806 /* 807 * HBA gets first crack 808 */ 809 810 status = aac_dev_ioctl(dev, cmd, arg); 811 if(status != -ENOTTY) 812 return status; 813 814 switch (cmd) { 815 case FSACTL_MINIPORT_REV_CHECK: 816 status = check_revision(dev, arg); 817 break; 818 case FSACTL_SEND_LARGE_FIB: 819 case FSACTL_SENDFIB: 820 status = ioctl_send_fib(dev, arg); 821 break; 822 case FSACTL_OPEN_GET_ADAPTER_FIB: 823 status = open_getadapter_fib(dev, arg); 824 break; 825 case FSACTL_GET_NEXT_ADAPTER_FIB: 826 status = next_getadapter_fib(dev, arg); 827 break; 828 case FSACTL_CLOSE_GET_ADAPTER_FIB: 829 status = close_getadapter_fib(dev, arg); 830 break; 831 case FSACTL_SEND_RAW_SRB: 832 status = aac_send_raw_srb(dev,arg); 833 break; 834 case FSACTL_GET_PCI_INFO: 835 status = aac_get_pci_info(dev,arg); 836 break; 837 default: 838 status = -ENOTTY; 839 break; 840 } 841 return status; 842 } 843 844