aachba.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:48k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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.  * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  *
  23.  */
  24. #include <linux/config.h>
  25. #include <linux/kernel.h>
  26. #include <linux/init.h>
  27. #include <linux/types.h>
  28. #include <linux/sched.h>
  29. #include <linux/pci.h>
  30. #include <linux/spinlock.h>
  31. #include <linux/slab.h>
  32. #include <linux/completion.h>
  33. #include <asm/semaphore.h>
  34. #include <asm/uaccess.h>
  35. #define MAJOR_NR SCSI_DISK0_MAJOR /* For DEVICE_NR() */
  36. #include <linux/blk.h>
  37. #include "scsi.h"
  38. #include "hosts.h"
  39. #include "sd.h"
  40. #include "aacraid.h"
  41. /* SCSI Commands */
  42. /* TODO:  dmb - use the ones defined in include/scsi/scsi.h */
  43. #define SS_TEST 0x00 /* Test unit ready */
  44. #define SS_REZERO 0x01 /* Rezero unit */
  45. #define SS_REQSEN 0x03 /* Request Sense */
  46. #define SS_REASGN 0x07 /* Reassign blocks */
  47. #define SS_READ 0x08 /* Read 6   */
  48. #define SS_WRITE 0x0A /* Write 6  */
  49. #define SS_INQUIR 0x12 /* inquiry */
  50. #define SS_ST_SP 0x1B /* Start/Stop unit */
  51. #define SS_LOCK 0x1E /* prevent/allow medium removal */
  52. #define SS_RESERV 0x16 /* Reserve */
  53. #define SS_RELES 0x17 /* Release */
  54. #define SS_MODESEN 0x1A /* Mode Sense 6 */
  55. #define SS_RDCAP 0x25 /* Read Capacity */
  56. #define SM_READ 0x28 /* Read 10  */
  57. #define SM_WRITE 0x2A /* Write 10 */
  58. #define SS_SEEK 0x2B /* Seek */
  59. /* values for inqd_pdt: Peripheral device type in plain English */
  60. #define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
  61. #define INQD_PDT_PROC 0x03 /* Processor device */
  62. #define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
  63. #define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
  64. #define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
  65. #define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
  66. #define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
  67. #define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
  68. #define TARGET_LUN_TO_CONTAINER(target, lun) (target)
  69. #define CONTAINER_TO_TARGET(cont) ((cont))
  70. #define CONTAINER_TO_LUN(cont) (0)
  71. #define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER))
  72. #define MAX_DRIVER_SG_SEGMENT_COUNT 17
  73. /*
  74.  * Sense keys
  75.  */
  76. #define SENKEY_NO_SENSE       0x00
  77. #define SENKEY_UNDEFINED      0x01
  78. #define SENKEY_NOT_READY      0x02
  79. #define SENKEY_MEDIUM_ERR     0x03
  80. #define SENKEY_HW_ERR         0x04
  81. #define SENKEY_ILLEGAL        0x05
  82. #define SENKEY_ATTENTION      0x06
  83. #define SENKEY_PROTECTED      0x07
  84. #define SENKEY_BLANK          0x08
  85. #define SENKEY_V_UNIQUE       0x09
  86. #define SENKEY_CPY_ABORT      0x0A
  87. #define SENKEY_ABORT          0x0B
  88. #define SENKEY_EQUAL          0x0C
  89. #define SENKEY_VOL_OVERFLOW   0x0D
  90. #define SENKEY_MISCOMP        0x0E
  91. #define SENKEY_RESERVED       0x0F
  92. /*
  93.  * Sense codes
  94.  */
  95.  
  96. #define SENCODE_NO_SENSE                        0x00
  97. #define SENCODE_END_OF_DATA                     0x00
  98. #define SENCODE_BECOMING_READY                  0x04
  99. #define SENCODE_INIT_CMD_REQUIRED               0x04
  100. #define SENCODE_PARAM_LIST_LENGTH_ERROR         0x1A
  101. #define SENCODE_INVALID_COMMAND                 0x20
  102. #define SENCODE_LBA_OUT_OF_RANGE                0x21
  103. #define SENCODE_INVALID_CDB_FIELD               0x24
  104. #define SENCODE_LUN_NOT_SUPPORTED               0x25
  105. #define SENCODE_INVALID_PARAM_FIELD             0x26
  106. #define SENCODE_PARAM_NOT_SUPPORTED             0x26
  107. #define SENCODE_PARAM_VALUE_INVALID             0x26
  108. #define SENCODE_RESET_OCCURRED                  0x29
  109. #define SENCODE_LUN_NOT_SELF_CONFIGURED_YET     0x3E
  110. #define SENCODE_INQUIRY_DATA_CHANGED            0x3F
  111. #define SENCODE_SAVING_PARAMS_NOT_SUPPORTED     0x39
  112. #define SENCODE_DIAGNOSTIC_FAILURE              0x40
  113. #define SENCODE_INTERNAL_TARGET_FAILURE         0x44
  114. #define SENCODE_INVALID_MESSAGE_ERROR           0x49
  115. #define SENCODE_LUN_FAILED_SELF_CONFIG          0x4c
  116. #define SENCODE_OVERLAPPED_COMMAND              0x4E
  117. /*
  118.  * Additional sense codes
  119.  */
  120.  
  121. #define ASENCODE_NO_SENSE                       0x00
  122. #define ASENCODE_END_OF_DATA                    0x05
  123. #define ASENCODE_BECOMING_READY                 0x01
  124. #define ASENCODE_INIT_CMD_REQUIRED              0x02
  125. #define ASENCODE_PARAM_LIST_LENGTH_ERROR        0x00
  126. #define ASENCODE_INVALID_COMMAND                0x00
  127. #define ASENCODE_LBA_OUT_OF_RANGE               0x00
  128. #define ASENCODE_INVALID_CDB_FIELD              0x00
  129. #define ASENCODE_LUN_NOT_SUPPORTED              0x00
  130. #define ASENCODE_INVALID_PARAM_FIELD            0x00
  131. #define ASENCODE_PARAM_NOT_SUPPORTED            0x01
  132. #define ASENCODE_PARAM_VALUE_INVALID            0x02
  133. #define ASENCODE_RESET_OCCURRED                 0x00
  134. #define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET    0x00
  135. #define ASENCODE_INQUIRY_DATA_CHANGED           0x03
  136. #define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED    0x00
  137. #define ASENCODE_DIAGNOSTIC_FAILURE             0x80
  138. #define ASENCODE_INTERNAL_TARGET_FAILURE        0x00
  139. #define ASENCODE_INVALID_MESSAGE_ERROR          0x00
  140. #define ASENCODE_LUN_FAILED_SELF_CONFIG         0x00
  141. #define ASENCODE_OVERLAPPED_COMMAND             0x00
  142. #define BYTE0(x) (unsigned char)(x)
  143. #define BYTE1(x) (unsigned char)((x) >> 8)
  144. #define BYTE2(x) (unsigned char)((x) >> 16)
  145. #define BYTE3(x) (unsigned char)((x) >> 24)
  146. /*------------------------------------------------------------------------------
  147.  *              S T R U C T S / T Y P E D E F S
  148.  *----------------------------------------------------------------------------*/
  149. /* SCSI inquiry data */
  150. struct inquiry_data {
  151. u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type  */
  152. u8 inqd_dtq; /* RMB | Device Type Qualifier  */
  153. u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
  154. u8 inqd_rdf; /* AENC | TrmIOP | Response data format */
  155. u8 inqd_len; /* Additional length (n-4) */
  156. u8 inqd_pad1[2]; /* Reserved - must be zero */
  157. u8 inqd_pad2; /* RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
  158. u8 inqd_vid[8]; /* Vendor ID */
  159. u8 inqd_pid[16]; /* Product ID */
  160. u8 inqd_prl[4]; /* Product Revision Level */
  161. };
  162. struct sense_data {
  163. u8 error_code; /* 70h (current errors), 71h(deferred errors) */
  164. u8 valid:1; /* A valid bit of one indicates that the information  */
  165. /* field contains valid information as defined in the
  166.  * SCSI-2 Standard.
  167.  */
  168. u8 segment_number; /* Only used for COPY, COMPARE, or COPY AND VERIFY Commands */
  169. u8 sense_key:4; /* Sense Key */
  170. u8 reserved:1;
  171. u8 ILI:1; /* Incorrect Length Indicator */
  172. u8 EOM:1; /* End Of Medium - reserved for random access devices */
  173. u8 filemark:1; /* Filemark - reserved for random access devices */
  174. u8 information[4]; /* for direct-access devices, contains the unsigned 
  175.  * logical block address or residue associated with 
  176.  * the sense key 
  177.  */
  178. u8 add_sense_len; /* number of additional sense bytes to follow this field */
  179. u8 cmnd_info[4]; /* not used */
  180. u8 ASC; /* Additional Sense Code */
  181. u8 ASCQ; /* Additional Sense Code Qualifier */
  182. u8 FRUC; /* Field Replaceable Unit Code - not used */
  183. u8 bit_ptr:3; /* indicates which byte of the CDB or parameter data
  184.  * was in error
  185.  */
  186. u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that 
  187.  * the bit_ptr field has valid value
  188.  */
  189. u8 reserved2:2;
  190. u8 CD:1; /* command data bit: 1- illegal parameter in CDB.
  191.  * 0- illegal parameter in data.
  192.  */
  193. u8 SKSV:1;
  194. u8 field_ptr[2]; /* byte of the CDB or parameter data in error */
  195. };
  196. /*
  197.  *              M O D U L E   G L O B A L S
  198.  */
  199.  
  200. static struct fsa_scsi_hba *fsa_dev[MAXIMUM_NUM_ADAPTERS]; /*  SCSI Device Instance Pointers */
  201. static struct sense_data sense_data[MAXIMUM_NUM_CONTAINERS];
  202. static void get_sd_devname(int disknum, char *buffer);
  203. static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* sgmap);
  204. static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg);
  205. static int aac_send_srb_fib(Scsi_Cmnd* scsicmd);
  206. #ifdef AAC_DETAILED_STATUS_INFO
  207. static char *aac_get_status_string(u32 status);
  208. #endif
  209. /**
  210.  * aac_get_containers - list containers
  211.  * @common: adapter to probe
  212.  *
  213.  * Make a list of all containers on this controller
  214.  */
  215. int aac_get_containers(struct aac_dev *dev)
  216. {
  217. struct fsa_scsi_hba *fsa_dev_ptr;
  218. u32 index, status = 0;
  219. struct aac_query_mount *dinfo;
  220. struct aac_mount *dresp;
  221. struct fib * fibptr;
  222. unsigned instance;
  223. fsa_dev_ptr = &(dev->fsa_dev);
  224. instance = dev->scsi_host_ptr->unique_id;
  225. if (!(fibptr = fib_alloc(dev)))
  226. return -ENOMEM;
  227. for (index = 0; index < MAXIMUM_NUM_CONTAINERS; index++) {
  228. fib_init(fibptr);
  229. dinfo = (struct aac_query_mount *) fib_data(fibptr);
  230. dinfo->command = cpu_to_le32(VM_NameServe);
  231. dinfo->count = cpu_to_le32(index);
  232. dinfo->type = cpu_to_le32(FT_FILESYS);
  233. status = fib_send(ContainerCommand,
  234.     fibptr,
  235.     sizeof (struct aac_query_mount),
  236.     FsaNormal,
  237.     1, 1,
  238.     NULL, NULL);
  239. if (status < 0 ) {
  240. printk(KERN_WARNING "ProbeContainers: SendFIB failed.n");
  241. break;
  242. }
  243. dresp = (struct aac_mount *)fib_data(fibptr);
  244. if ((le32_to_cpu(dresp->status) == ST_OK) &&
  245.     (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
  246. fsa_dev_ptr->valid[index] = 1;
  247. fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol);
  248. fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity);
  249. if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
  250.     fsa_dev_ptr->ro[index] = 1;
  251. }
  252. fib_complete(fibptr);
  253. /*
  254.  * If there are no more containers, then stop asking.
  255.  */
  256. if ((index + 1) >= le32_to_cpu(dresp->count))
  257. break;
  258. }
  259. fib_free(fibptr);
  260. fsa_dev[instance] = fsa_dev_ptr;
  261. return status;
  262. }
  263. /**
  264.  * probe_container - query a logical volume
  265.  * @dev: device to query
  266.  * @cid: container identifier
  267.  *
  268.  * Queries the controller about the given volume. The volume information
  269.  * is updated in the struct fsa_scsi_hba structure rather than returned.
  270.  */
  271.  
  272. static int probe_container(struct aac_dev *dev, int cid)
  273. {
  274. struct fsa_scsi_hba *fsa_dev_ptr;
  275. int status;
  276. struct aac_query_mount *dinfo;
  277. struct aac_mount *dresp;
  278. struct fib * fibptr;
  279. unsigned instance;
  280. fsa_dev_ptr = &(dev->fsa_dev);
  281. instance = dev->scsi_host_ptr->unique_id;
  282. if (!(fibptr = fib_alloc(dev)))
  283. return -ENOMEM;
  284. fib_init(fibptr);
  285. dinfo = (struct aac_query_mount *)fib_data(fibptr);
  286. dinfo->command = cpu_to_le32(VM_NameServe);
  287. dinfo->count = cpu_to_le32(cid);
  288. dinfo->type = cpu_to_le32(FT_FILESYS);
  289. status = fib_send(ContainerCommand,
  290.     fibptr,
  291.     sizeof(struct aac_query_mount),
  292.     FsaNormal,
  293.     1, 1,
  294.     NULL, NULL);
  295. if (status < 0) {
  296. printk(KERN_WARNING "aacraid: probe_containers query failed.n");
  297. goto error;
  298. }
  299. dresp = (struct aac_mount *) fib_data(fibptr);
  300. if ((le32_to_cpu(dresp->status) == ST_OK) &&
  301.     (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
  302. fsa_dev_ptr->valid[cid] = 1;
  303. fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol);
  304. fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity);
  305. if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)
  306. fsa_dev_ptr->ro[cid] = 1;
  307. }
  308. error:
  309. fib_complete(fibptr);
  310. fib_free(fibptr);
  311. return status;
  312. }
  313. /* Local Structure to set SCSI inquiry data strings */
  314. struct scsi_inq {
  315. char vid[8];         /* Vendor ID */
  316. char pid[16];        /* Product ID */
  317. char prl[4];         /* Product Revision Level */
  318. };
  319. /**
  320.  * InqStrCopy - string merge
  321.  * @a: string to copy from
  322.  * @b: string to copy to
  323.  *
  324.  *  Copy a String from one location to another
  325.  * without copying 
  326.  */
  327. static void inqstrcpy(char *a, char *b)
  328. {
  329. while(*a != (char)0) 
  330. *b++ = *a++;
  331. }
  332. static char *container_types[] = {
  333.         "None",
  334.         "Volume",
  335.         "Mirror",
  336.         "Stripe",
  337.         "RAID5",
  338.         "SSRW",
  339.         "SSRO",
  340.         "Morph",
  341.         "Legacy",
  342.         "RAID4",
  343.         "RAID10",             
  344.         "RAID00",             
  345.         "V-MIRRORS",          
  346.         "PSEUDO R4",          
  347. "RAID50",
  348.         "Unknown"
  349. };
  350. /* Function: setinqstr
  351.  *
  352.  * Arguments: [1] pointer to void [1] int
  353.  *
  354.  * Purpose: Sets SCSI inquiry data strings for vendor, product
  355.  * and revision level. Allows strings to be set in platform dependant
  356.  * files instead of in OS dependant driver source.
  357.  */
  358. static void setinqstr(int devtype, void *data, int tindex)
  359. {
  360. struct scsi_inq *str;
  361. char *findit;
  362. struct aac_driver_ident *mp;
  363. mp = aac_get_driver_ident(devtype);
  364.    
  365. str = (struct scsi_inq *)(data); /* cast data to scsi inq block */
  366. inqstrcpy (mp->vname, str->vid); 
  367. inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */
  368. findit = str->pid;
  369. for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
  370. findit++;
  371. if (tindex < (sizeof(container_types)/sizeof(char *))){
  372. inqstrcpy (container_types[tindex], findit);
  373. }
  374. inqstrcpy ("V1.0", str->prl);
  375. }
  376. void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
  377.     u8 a_sense_code, u8 incorrect_length,
  378.     u8 bit_pointer, u16 field_pointer,
  379.     u32 residue)
  380. {
  381. sense_buf[0] = 0xF0; /* Sense data valid, err code 70h (current error) */
  382. sense_buf[1] = 0; /* Segment number, always zero */
  383. if (incorrect_length) {
  384. sense_buf[2] = sense_key | 0x20; /* Set ILI bit | sense key */
  385. sense_buf[3] = BYTE3(residue);
  386. sense_buf[4] = BYTE2(residue);
  387. sense_buf[5] = BYTE1(residue);
  388. sense_buf[6] = BYTE0(residue);
  389. } else
  390. sense_buf[2] = sense_key; /* Sense key */
  391. if (sense_key == SENKEY_ILLEGAL)
  392. sense_buf[7] = 10; /* Additional sense length */
  393. else
  394. sense_buf[7] = 6; /* Additional sense length */
  395. sense_buf[12] = sense_code; /* Additional sense code */
  396. sense_buf[13] = a_sense_code; /* Additional sense code qualifier */
  397. if (sense_key == SENKEY_ILLEGAL) {
  398. sense_buf[15] = 0;
  399. if (sense_code == SENCODE_INVALID_PARAM_FIELD)
  400. sense_buf[15] = 0x80; /* Std sense key specific field */
  401. /* Illegal parameter is in the parameter block */
  402. if (sense_code == SENCODE_INVALID_CDB_FIELD)
  403. sense_buf[15] = 0xc0; /* Std sense key specific field */
  404. /* Illegal parameter is in the CDB block */
  405. sense_buf[15] |= bit_pointer;
  406. sense_buf[16] = field_pointer >> 8; /* MSB */
  407. sense_buf[17] = field_pointer; /* LSB */
  408. }
  409. }
  410. static void aac_io_done(Scsi_Cmnd * scsicmd)
  411. {
  412. unsigned long cpu_flags;
  413. spin_lock_irqsave(&io_request_lock, cpu_flags);
  414. scsicmd->scsi_done(scsicmd);
  415. spin_unlock_irqrestore(&io_request_lock, cpu_flags);
  416. }
  417. static void __aac_io_done(Scsi_Cmnd * scsicmd)
  418. {
  419. scsicmd->scsi_done(scsicmd);
  420. }
  421. int aac_get_adapter_info(struct aac_dev* dev)
  422. {
  423. struct fib* fibptr;
  424. struct aac_adapter_info* info;
  425. int rcode;
  426. u32 tmp;
  427. if (!(fibptr = fib_alloc(dev)))
  428. return -ENOMEM;
  429. fib_init(fibptr);
  430. info = (struct aac_adapter_info*) fib_data(fibptr);
  431. memset(info,0,sizeof(struct aac_adapter_info));
  432. rcode = fib_send(RequestAdapterInfo,
  433. fibptr, 
  434. sizeof(struct aac_adapter_info),
  435. FsaNormal, 
  436. 1, 1, 
  437. NULL, 
  438. NULL);
  439. memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info));
  440. tmp = dev->adapter_info.kernelrev;
  441. printk(KERN_INFO "%s%d: kernel %d.%d.%d build %dn", 
  442. dev->name, dev->id,
  443. tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,
  444. dev->adapter_info.kernelbuild);
  445. tmp = dev->adapter_info.monitorrev;
  446. printk(KERN_INFO "%s%d: monitor %d.%d.%d build %dn", 
  447. dev->name, dev->id,
  448. tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,
  449. dev->adapter_info.monitorbuild);
  450. tmp = dev->adapter_info.biosrev;
  451. printk(KERN_INFO "%s%d: bios %d.%d.%d build %dn", 
  452. dev->name, dev->id,
  453. tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,
  454. dev->adapter_info.biosbuild);
  455. printk(KERN_INFO "%s%d: serial %x%xn",
  456. dev->name, dev->id,
  457. dev->adapter_info.serial[0],
  458. dev->adapter_info.serial[1]);
  459. dev->pae_support = 0;
  460. dev->nondasd_support = 0;
  461. if( BITS_PER_LONG >= 64 && 
  462.   (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
  463. printk(KERN_INFO "%s%d: 64 Bit PAE enabledn", dev->name, dev->id);
  464. dev->pae_support = 1;
  465. }
  466. /* TODO - dmb temporary until fw can set this bit  */
  467. dev->pae_support = (BITS_PER_LONG >= 64);
  468. if(dev->pae_support != 0) {
  469. printk(KERN_INFO "%s%d: 64 Bit PAE enabledn", dev->name, dev->id);
  470. }
  471. if(dev->adapter_info.options & AAC_OPT_NONDASD){
  472. dev->nondasd_support = 1;
  473. }
  474. return rcode;
  475. }
  476. static void read_callback(void *context, struct fib * fibptr)
  477. {
  478. struct aac_dev *dev;
  479. struct aac_read_reply *readreply;
  480. Scsi_Cmnd *scsicmd;
  481. u32 lba;
  482. u32 cid;
  483. scsicmd = (Scsi_Cmnd *) context;
  484. dev = (struct aac_dev *)scsicmd->host->hostdata;
  485. cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
  486. lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
  487. dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, t = %ld.n", smp_processor_id(), lba, jiffies));
  488. if (fibptr == NULL)
  489. BUG();
  490. if(scsicmd->use_sg)
  491. pci_unmap_sg(dev->pdev, 
  492. (struct scatterlist *)scsicmd->buffer,
  493. scsicmd->use_sg,
  494. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  495. else if(scsicmd->request_bufflen)
  496. pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr,
  497.  scsicmd->request_bufflen,
  498.  scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  499. readreply = (struct aac_read_reply *)fib_data(fibptr);
  500. if (le32_to_cpu(readreply->status) == ST_OK)
  501. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  502. else {
  503. printk(KERN_WARNING "read_callback: read failed, status = %dn", readreply->status);
  504. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
  505. set_sense((u8 *) &sense_data[cid],
  506.     SENKEY_HW_ERR,
  507.     SENCODE_INTERNAL_TARGET_FAILURE,
  508.     ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
  509.     0, 0);
  510. }
  511. fib_complete(fibptr);
  512. fib_free(fibptr);
  513. aac_io_done(scsicmd);
  514. }
  515. static void write_callback(void *context, struct fib * fibptr)
  516. {
  517. struct aac_dev *dev;
  518. struct aac_write_reply *writereply;
  519. Scsi_Cmnd *scsicmd;
  520. u32 lba;
  521. u32 cid;
  522. scsicmd = (Scsi_Cmnd *) context;
  523. dev = (struct aac_dev *)scsicmd->host->hostdata;
  524. cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
  525. lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
  526. dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, t = %ld.n", smp_processor_id(), lba, jiffies));
  527. if (fibptr == NULL)
  528. BUG();
  529. if(scsicmd->use_sg)
  530. pci_unmap_sg(dev->pdev, 
  531. (struct scatterlist *)scsicmd->buffer,
  532. scsicmd->use_sg,
  533. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  534. else if(scsicmd->request_bufflen)
  535. pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr,
  536.  scsicmd->request_bufflen,
  537.  scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  538. writereply = (struct aac_write_reply *) fib_data(fibptr);
  539. if (le32_to_cpu(writereply->status) == ST_OK)
  540. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  541. else {
  542. printk(KERN_WARNING "write_callback: write failed, status = %dn", writereply->status);
  543. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
  544. set_sense((u8 *) &sense_data[cid],
  545.     SENKEY_HW_ERR,
  546.     SENCODE_INTERNAL_TARGET_FAILURE,
  547.     ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
  548.     0, 0);
  549. }
  550. fib_complete(fibptr);
  551. fib_free(fibptr);
  552. aac_io_done(scsicmd);
  553. }
  554. int aac_read(Scsi_Cmnd * scsicmd, int cid)
  555. {
  556. u32 lba;
  557. u32 count;
  558. int status;
  559. u16 fibsize;
  560. struct aac_dev *dev;
  561. struct fib * cmd_fibcontext;
  562. dev = (struct aac_dev *)scsicmd->host->hostdata;
  563. /*
  564.  * Get block address and transfer length
  565.  */
  566. if (scsicmd->cmnd[0] == SS_READ) /* 6 byte command */
  567. {
  568. dprintk((KERN_DEBUG "aachba: received a read(6) command on target %d.n", cid));
  569. lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
  570. count = scsicmd->cmnd[4];
  571. if (count == 0)
  572. count = 256;
  573. } else {
  574. dprintk((KERN_DEBUG "aachba: received a read(10) command on target %d.n", cid));
  575. lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
  576. count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
  577. }
  578. dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.n", smp_processor_id(), lba, jiffies));
  579. /*
  580.  * Alocate and initialize a Fib
  581.  */
  582. if (!(cmd_fibcontext = fib_alloc(dev))) {
  583. scsicmd->result = DID_ERROR << 16;
  584. aac_io_done(scsicmd);
  585. return (-1);
  586. }
  587. fib_init(cmd_fibcontext);
  588. if(dev->pae_support == 1){
  589. struct aac_read64 *readcmd;
  590. readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
  591. readcmd->command = cpu_to_le32(VM_CtHostRead64);
  592. readcmd->cid = cpu_to_le16(cid);
  593. readcmd->sector_count = cpu_to_le16(count);
  594. readcmd->block = cpu_to_le32(lba);
  595. readcmd->pad   = cpu_to_le16(0);
  596. readcmd->flags = cpu_to_le16(0); 
  597. aac_build_sg64(scsicmd, &readcmd->sg);
  598. if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)
  599. BUG();
  600. fibsize = sizeof(struct aac_read64) + ((readcmd->sg.count - 1) * sizeof (struct sgentry64));
  601. /*
  602.  * Now send the Fib to the adapter
  603.  */
  604. status = fib_send(ContainerCommand64, 
  605.   cmd_fibcontext, 
  606.   fibsize, 
  607.   FsaNormal, 
  608.   0, 1, 
  609.   (fib_callback) read_callback, 
  610.   (void *) scsicmd);
  611. } else {
  612. struct aac_read *readcmd;
  613. readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
  614. readcmd->command = cpu_to_le32(VM_CtBlockRead);
  615. readcmd->cid = cpu_to_le32(cid);
  616. readcmd->block = cpu_to_le32(lba);
  617. readcmd->count = cpu_to_le32(count * 512);
  618. if (count * 512 > (64 * 1024))
  619. BUG();
  620. aac_build_sg(scsicmd, &readcmd->sg);
  621. if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)
  622. BUG();
  623. fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry));
  624. /*
  625.  * Now send the Fib to the adapter
  626.  */
  627. status = fib_send(ContainerCommand, 
  628.   cmd_fibcontext, 
  629.   fibsize, 
  630.   FsaNormal, 
  631.   0, 1, 
  632.   (fib_callback) read_callback, 
  633.   (void *) scsicmd);
  634. }
  635. /*
  636.  * Check that the command queued to the controller
  637.  */
  638. if (status == -EINPROGRESS) 
  639. return 0;
  640. printk(KERN_WARNING "aac_read: fib_send failed with status: %d.n", status);
  641. /*
  642.  * For some reason, the Fib didn't queue, return QUEUE_FULL
  643.  */
  644. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;
  645. aac_io_done(scsicmd);
  646. fib_complete(cmd_fibcontext);
  647. fib_free(cmd_fibcontext);
  648. return -1;
  649. }
  650. static int aac_write(Scsi_Cmnd * scsicmd, int cid)
  651. {
  652. u32 lba;
  653. u32 count;
  654. int status;
  655. u16 fibsize;
  656. struct aac_dev *dev;
  657. struct fib * cmd_fibcontext;
  658. dev = (struct aac_dev *)scsicmd->host->hostdata;
  659. /*
  660.  * Get block address and transfer length
  661.  */
  662. if (scsicmd->cmnd[0] == SS_WRITE) /* 6 byte command */
  663. {
  664. lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
  665. count = scsicmd->cmnd[4];
  666. if (count == 0)
  667. count = 256;
  668. } else {
  669. dprintk((KERN_DEBUG "aachba: received a write(10) command on target %d.n", cid));
  670. lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
  671. count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
  672. }
  673. dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %lu, t = %ld.n", smp_processor_id(), lba, jiffies));
  674. /*
  675.  * Allocate and initialize a Fib then setup a BlockWrite command
  676.  */
  677. if (!(cmd_fibcontext = fib_alloc(dev))) {
  678. scsicmd->result = DID_ERROR << 16;
  679. aac_io_done(scsicmd);
  680. return -1;
  681. }
  682. fib_init(cmd_fibcontext);
  683. if(dev->pae_support == 1)
  684. {
  685. struct aac_write64 *writecmd;
  686. writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
  687. writecmd->command = cpu_to_le32(VM_CtHostWrite64);
  688. writecmd->cid = cpu_to_le16(cid);
  689. writecmd->sector_count = cpu_to_le16(count); 
  690. writecmd->block = cpu_to_le32(lba);
  691. writecmd->pad = cpu_to_le16(0);
  692. writecmd->flags = cpu_to_le16(0);
  693. aac_build_sg64(scsicmd, &writecmd->sg);
  694. if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)
  695. BUG();
  696. fibsize = sizeof(struct aac_write64) + ((writecmd->sg.count - 1) * sizeof (struct sgentry64));
  697. /*
  698.  * Now send the Fib to the adapter
  699.  */
  700. status = fib_send(ContainerCommand64, 
  701.   cmd_fibcontext, 
  702.   fibsize, 
  703.   FsaNormal, 
  704.   0, 1, 
  705.   (fib_callback) write_callback, 
  706.   (void *) scsicmd);
  707. }
  708. else 
  709. {
  710. struct aac_write *writecmd;
  711. writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
  712. writecmd->command = cpu_to_le32(VM_CtBlockWrite);
  713. writecmd->cid = cpu_to_le32(cid);
  714. writecmd->block = cpu_to_le32(lba);
  715. writecmd->count = cpu_to_le32(count * 512);
  716. writecmd->sg.count = cpu_to_le32(1);
  717. /* ->stable is not used - it did mean which type of write */
  718. if (count * 512 > (64 * 1024))
  719. BUG();
  720. aac_build_sg(scsicmd, &writecmd->sg);
  721. if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)
  722. BUG();
  723. fibsize = sizeof(struct aac_write) + ((writecmd->sg.count - 1) * sizeof (struct sgentry));
  724. /*
  725.  * Now send the Fib to the adapter
  726.  */
  727. status = fib_send(ContainerCommand, 
  728.   cmd_fibcontext, 
  729.   fibsize, 
  730.   FsaNormal, 
  731.   0, 1, 
  732.   (fib_callback) write_callback, 
  733.   (void *) scsicmd);
  734. }
  735. /*
  736.  * Check that the command queued to the controller
  737.  */
  738. if (status == -EINPROGRESS)
  739. return 0;
  740. printk(KERN_WARNING "aac_write: fib_send failed with status: %dn", status);
  741. /*
  742.  * For some reason, the Fib didn't queue, return QUEUE_FULL
  743.  */
  744. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;
  745. aac_io_done(scsicmd);
  746. fib_complete(cmd_fibcontext);
  747. fib_free(cmd_fibcontext);
  748. return -1;
  749. }
  750. /**
  751.  * aac_scsi_cmd() - Process SCSI command
  752.  * @scsicmd: SCSI command block
  753.  * @wait: 1 if the user wants to await completion
  754.  *
  755.  * Emulate a SCSI command and queue the required request for the
  756.  * aacraid firmware.
  757.  */
  758.  
  759. int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
  760. {
  761. u32 cid = 0;
  762. struct fsa_scsi_hba *fsa_dev_ptr;
  763. int cardtype;
  764. int ret;
  765. struct aac_dev *dev = (struct aac_dev *)scsicmd->host->hostdata;
  766. cardtype = dev->cardtype;
  767. fsa_dev_ptr = fsa_dev[scsicmd->host->unique_id];
  768. /*
  769.  * If the bus, target or lun is out of range, return fail
  770.  * Test does not apply to ID 16, the pseudo id for the controller
  771.  * itself.
  772.  */
  773. if (scsicmd->target != scsicmd->host->this_id) {
  774. if ((scsicmd->channel == 0) ){
  775. if( (scsicmd->target >= AAC_MAX_TARGET) || (scsicmd->lun != 0)){ 
  776. scsicmd->result = DID_NO_CONNECT << 16;
  777. __aac_io_done(scsicmd);
  778. return 0;
  779. }
  780. cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);
  781. /*
  782.  * If the target container doesn't exist, it may have
  783.  * been newly created
  784.  */
  785. if (fsa_dev_ptr->valid[cid] == 0) {
  786. switch (scsicmd->cmnd[0]) {
  787. case SS_INQUIR:
  788. case SS_RDCAP:
  789. case SS_TEST:
  790. spin_unlock_irq(&io_request_lock);
  791. probe_container(dev, cid);
  792. spin_lock_irq(&io_request_lock);
  793. if (fsa_dev_ptr->valid[cid] == 0) {
  794. scsicmd->result = DID_NO_CONNECT << 16;
  795. __aac_io_done(scsicmd);
  796. return 0;
  797. }
  798. default:
  799. break;
  800. }
  801. }
  802. /*
  803.  * If the target container still doesn't exist, 
  804.  * return failure
  805.  */
  806. if (fsa_dev_ptr->valid[cid] == 0) {
  807. scsicmd->result = DID_BAD_TARGET << 16;
  808. __aac_io_done(scsicmd);
  809. return -1;
  810. }
  811. } else {  /* check for physical non-dasd devices */
  812. if(dev->nondasd_support == 1){
  813. return aac_send_srb_fib(scsicmd);
  814. } else {
  815. scsicmd->result = DID_NO_CONNECT << 16;
  816. __aac_io_done(scsicmd);
  817. return 0;
  818. }
  819. }
  820. }
  821. /*
  822.  * else Command for the controller itself
  823.  */
  824. else if ((scsicmd->cmnd[0] != SS_INQUIR) && /* only INQUIRY & TUR cmnd supported for controller */
  825. (scsicmd->cmnd[0] != SS_TEST)) 
  826. {
  827. dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.n", scsicmd->cmnd[0]));
  828. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
  829. set_sense((u8 *) &sense_data[cid],
  830.     SENKEY_ILLEGAL,
  831.     SENCODE_INVALID_COMMAND,
  832.     ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);
  833. __aac_io_done(scsicmd);
  834. return -1;
  835. }
  836. /* Handle commands here that don't really require going out to the adapter */
  837. switch (scsicmd->cmnd[0]) {
  838. case SS_INQUIR:
  839. {
  840. struct inquiry_data *inq_data_ptr;
  841. dprintk((KERN_DEBUG "INQUIRY command, ID: %d.n", scsicmd->target));
  842. inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer;
  843. memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
  844. inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */
  845. inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */
  846. inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
  847. inq_data_ptr->inqd_len = 31;
  848. /*Format for "pad2" is  RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
  849. inq_data_ptr->inqd_pad2= 0x32 ;  /*WBus16|Sync|CmdQue */
  850. /*
  851.  * Set the Vendor, Product, and Revision Level
  852.  * see: <vendor>.c i.e. aac.c
  853.  */
  854. setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]);
  855. if (scsicmd->target == scsicmd->host->this_id)
  856. inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */
  857. else
  858. inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
  859. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  860. __aac_io_done(scsicmd);
  861. return 0;
  862. }
  863. case SS_RDCAP:
  864. {
  865. int capacity;
  866. char *cp;
  867. dprintk((KERN_DEBUG "READ CAPACITY command.n"));
  868. capacity = fsa_dev_ptr->size[cid] - 1;
  869. cp = scsicmd->request_buffer;
  870. cp[0] = (capacity >> 24) & 0xff;
  871. cp[1] = (capacity >> 16) & 0xff;
  872. cp[2] = (capacity >> 8) & 0xff;
  873. cp[3] = (capacity >> 0) & 0xff;
  874. cp[4] = 0;
  875. cp[5] = 0;
  876. cp[6] = 2;
  877. cp[7] = 0;
  878. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  879. __aac_io_done(scsicmd);
  880. return 0;
  881. }
  882. case SS_MODESEN:
  883. {
  884. char *mode_buf;
  885. dprintk((KERN_DEBUG "MODE SENSE command.n"));
  886. mode_buf = scsicmd->request_buffer;
  887. mode_buf[0] = 0; /* Mode data length (MSB) */
  888. mode_buf[1] = 6; /* Mode data length (LSB) */
  889. mode_buf[2] = 0; /* Medium type - default */
  890. mode_buf[3] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */
  891. mode_buf[4] = 0; /* reserved */
  892. mode_buf[5] = 0; /* reserved */
  893. mode_buf[6] = 0; /* Block descriptor length (MSB) */
  894. mode_buf[7] = 0; /* Block descriptor length (LSB) */
  895. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  896. __aac_io_done(scsicmd);
  897. return 0;
  898. }
  899. case SS_REQSEN:
  900. dprintk((KERN_DEBUG "REQUEST SENSE command.n"));
  901. memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof (struct sense_data));
  902. memset(&sense_data[cid], 0, sizeof (struct sense_data));
  903. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  904. __aac_io_done(scsicmd);
  905. return (0);
  906. case SS_LOCK:
  907. dprintk((KERN_DEBUG "LOCK command.n"));
  908. if (scsicmd->cmnd[4])
  909. fsa_dev_ptr->locked[cid] = 1;
  910. else
  911. fsa_dev_ptr->locked[cid] = 0;
  912. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  913. __aac_io_done(scsicmd);
  914. return 0;
  915. /*
  916.  * These commands are all No-Ops
  917.  */
  918. case SS_TEST:
  919. case SS_RESERV:
  920. case SS_RELES:
  921. case SS_REZERO:
  922. case SS_REASGN:
  923. case SS_SEEK:
  924. case SS_ST_SP:
  925. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
  926. __aac_io_done(scsicmd);
  927. return (0);
  928. }
  929. switch (scsicmd->cmnd[0]) 
  930. {
  931. case SS_READ:
  932. case SM_READ:
  933. /*
  934.  * Hack to keep track of ordinal number of the device that
  935.  * corresponds to a container. Needed to convert
  936.  * containers to /dev/sd device names
  937.  */
  938.  
  939. spin_unlock_irq(&io_request_lock);
  940. fsa_dev_ptr->devno[cid] = DEVICE_NR(scsicmd->request.rq_dev);
  941. ret = aac_read(scsicmd, cid);
  942. spin_lock_irq(&io_request_lock);
  943. return ret;
  944. case SS_WRITE:
  945. case SM_WRITE:
  946. spin_unlock_irq(&io_request_lock);
  947. ret = aac_write(scsicmd, cid);
  948. spin_lock_irq(&io_request_lock);
  949. return ret;
  950. default:
  951. /*
  952.  * Unhandled commands
  953.  */
  954. printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.n", scsicmd->cmnd[0]);
  955. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
  956. set_sense((u8 *) &sense_data[cid],
  957. SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND,
  958. ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);
  959. __aac_io_done(scsicmd);
  960. return -1;
  961. }
  962. }
  963. static int query_disk(struct aac_dev *dev, void *arg)
  964. {
  965. struct aac_query_disk qd;
  966. struct fsa_scsi_hba *fsa_dev_ptr;
  967. fsa_dev_ptr = &(dev->fsa_dev);
  968. if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
  969. return -EFAULT;
  970. if (qd.cnum == -1)
  971. qd.cnum = TARGET_LUN_TO_CONTAINER(qd.target, qd.lun);
  972. else if ((qd.bus == -1) && (qd.target == -1) && (qd.lun == -1)) 
  973. {
  974. if (qd.cnum < 0 || qd.cnum > MAXIMUM_NUM_CONTAINERS)
  975. return -EINVAL;
  976. qd.instance = dev->scsi_host_ptr->host_no;
  977. qd.bus = 0;
  978. qd.target = CONTAINER_TO_TARGET(qd.cnum);
  979. qd.lun = CONTAINER_TO_LUN(qd.cnum);
  980. }
  981. else return -EINVAL;
  982. qd.valid = fsa_dev_ptr->valid[qd.cnum];
  983. qd.locked = fsa_dev_ptr->locked[qd.cnum];
  984. qd.deleted = fsa_dev_ptr->deleted[qd.cnum];
  985. if (fsa_dev_ptr->devno[qd.cnum] == -1)
  986. qd.unmapped = 1;
  987. else
  988. qd.unmapped = 0;
  989. get_sd_devname(fsa_dev_ptr->devno[qd.cnum], qd.name);
  990. if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk)))
  991. return -EFAULT;
  992. return 0;
  993. }
  994. static void get_sd_devname(int disknum, char *buffer)
  995. {
  996. if (disknum < 0) {
  997. sprintf(buffer, "%s", "");
  998. return;
  999. }
  1000. if (disknum < 26)
  1001. sprintf(buffer, "sd%c", 'a' + disknum);
  1002. else {
  1003. unsigned int min1;
  1004. unsigned int min2;
  1005. /*
  1006.  * For larger numbers of disks, we need to go to a new
  1007.  * naming scheme.
  1008.  */
  1009. min1 = disknum / 26;
  1010. min2 = disknum % 26;
  1011. sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
  1012. }
  1013. }
  1014. static int force_delete_disk(struct aac_dev *dev, void *arg)
  1015. {
  1016. struct aac_delete_disk dd;
  1017. struct fsa_scsi_hba *fsa_dev_ptr;
  1018. fsa_dev_ptr = &(dev->fsa_dev);
  1019. if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
  1020. return -EFAULT;
  1021. if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
  1022. return -EINVAL;
  1023. /*
  1024.  * Mark this container as being deleted.
  1025.  */
  1026. fsa_dev_ptr->deleted[dd.cnum] = 1;
  1027. /*
  1028.  * Mark the container as no longer valid
  1029.  */
  1030. fsa_dev_ptr->valid[dd.cnum] = 0;
  1031. return 0;
  1032. }
  1033. static int delete_disk(struct aac_dev *dev, void *arg)
  1034. {
  1035. struct aac_delete_disk dd;
  1036. struct fsa_scsi_hba *fsa_dev_ptr;
  1037. fsa_dev_ptr = &(dev->fsa_dev);
  1038. if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
  1039. return -EFAULT;
  1040. if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
  1041. return -EINVAL;
  1042. /*
  1043.  * If the container is locked, it can not be deleted by the API.
  1044.  */
  1045. if (fsa_dev_ptr->locked[dd.cnum])
  1046. return -EBUSY;
  1047. else {
  1048. /*
  1049.  * Mark the container as no longer being valid.
  1050.  */
  1051. fsa_dev_ptr->valid[dd.cnum] = 0;
  1052. fsa_dev_ptr->devno[dd.cnum] = -1;
  1053. return 0;
  1054. }
  1055. }
  1056. int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg)
  1057. {
  1058. switch (cmd) {
  1059. case FSACTL_QUERY_DISK:
  1060. return query_disk(dev, arg);
  1061. case FSACTL_DELETE_DISK:
  1062. return delete_disk(dev, arg);
  1063. case FSACTL_FORCE_DELETE_DISK:
  1064. return force_delete_disk(dev, arg);
  1065. case 2131:
  1066. return aac_get_containers(dev);
  1067. default:
  1068. return -ENOTTY;
  1069. }
  1070. }
  1071. /**
  1072.  *
  1073.  * aac_srb_callback
  1074.  * @context: the context set in the fib - here it is scsi cmd
  1075.  * @fibptr: pointer to the fib
  1076.  *
  1077.  * Handles the completion of a scsi command to a non dasd device
  1078.  *
  1079.  */
  1080. static void aac_srb_callback(void *context, struct fib * fibptr)
  1081. {
  1082. struct aac_dev *dev;
  1083. struct aac_srb_reply *srbreply;
  1084. Scsi_Cmnd *scsicmd;
  1085. scsicmd = (Scsi_Cmnd *) context;
  1086. dev = (struct aac_dev *)scsicmd->host->hostdata;
  1087. if (fibptr == NULL)
  1088. BUG();
  1089. srbreply = (struct aac_srb_reply *) fib_data(fibptr);
  1090. scsicmd->sense_buffer[0] = '';  // initialize sense valid flag to false
  1091. // calculate resid for sg 
  1092. scsicmd->resid = scsicmd->request_bufflen - srbreply->data_xfer_length;
  1093. if(scsicmd->use_sg)
  1094. pci_unmap_sg(dev->pdev, 
  1095. (struct scatterlist *)scsicmd->buffer,
  1096. scsicmd->use_sg,
  1097. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1098. else if(scsicmd->request_bufflen)
  1099. pci_unmap_single(dev->pdev, (ulong)scsicmd->SCp.ptr, scsicmd->request_bufflen,
  1100. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1101. /*
  1102.  * First check the fib status
  1103.  */
  1104. if (le32_to_cpu(srbreply->status) != ST_OK){
  1105. int len;
  1106. printk(KERN_WARNING "aac_srb_callback: srb failed, status = %dn", le32_to_cpu(srbreply->status));
  1107. len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))?
  1108. sizeof(scsicmd->sense_buffer):srbreply->sense_data_size;
  1109. scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
  1110. memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
  1111. }
  1112. /*
  1113.  * Next check the srb status
  1114.  */
  1115. switch(le32_to_cpu(srbreply->srb_status)){
  1116. case SRB_STATUS_ERROR_RECOVERY:
  1117. case SRB_STATUS_PENDING:
  1118. case SRB_STATUS_SUCCESS:
  1119. if(scsicmd->cmnd[0] == INQUIRY ){
  1120. u8 b;
  1121. /* We can't expose disk devices because we can't tell whether they
  1122.  * are the raw container drives or stand alone drives
  1123.  */
  1124. b = *(u8*)scsicmd->buffer;
  1125. if( (b & 0x0f) == TYPE_DISK ){
  1126. scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
  1127. }
  1128. } else {
  1129. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
  1130. }
  1131. break;
  1132. case SRB_STATUS_DATA_OVERRUN:
  1133. switch(scsicmd->cmnd[0]){
  1134. case  READ_6:
  1135. case  WRITE_6:
  1136. case  READ_10:
  1137. case  WRITE_10:
  1138. case  READ_12:
  1139. case  WRITE_12:
  1140. if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) {
  1141. printk(KERN_WARNING"aacraid: SCSI CMD underflown");
  1142. } else {
  1143. printk(KERN_WARNING"aacraid: SCSI CMD Data Overrunn");
  1144. }
  1145. scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
  1146. break;
  1147. default:
  1148. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
  1149. break;
  1150. }
  1151. break;
  1152. case SRB_STATUS_ABORTED:
  1153. scsicmd->result = DID_ABORT << 16 | ABORT << 8;
  1154. break;
  1155. case SRB_STATUS_ABORT_FAILED:
  1156. // Not sure about this one - but assuming the hba was trying to abort for some reason
  1157. scsicmd->result = DID_ERROR << 16 | ABORT << 8;
  1158. break;
  1159. case SRB_STATUS_PARITY_ERROR:
  1160. scsicmd->result = DID_PARITY << 16 | MSG_PARITY_ERROR << 8;
  1161. break;
  1162. case SRB_STATUS_NO_DEVICE:
  1163. case SRB_STATUS_INVALID_PATH_ID:
  1164. case SRB_STATUS_INVALID_TARGET_ID:
  1165. case SRB_STATUS_INVALID_LUN:
  1166. case SRB_STATUS_SELECTION_TIMEOUT:
  1167. scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
  1168. break;
  1169. case SRB_STATUS_COMMAND_TIMEOUT:
  1170. case SRB_STATUS_TIMEOUT:
  1171. scsicmd->result = DID_TIME_OUT << 16 | COMMAND_COMPLETE << 8;
  1172. break;
  1173. case SRB_STATUS_BUSY:
  1174. scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
  1175. break;
  1176. case SRB_STATUS_BUS_RESET:
  1177. scsicmd->result = DID_RESET << 16 | COMMAND_COMPLETE << 8;
  1178. break;
  1179. case SRB_STATUS_MESSAGE_REJECTED:
  1180. scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;
  1181. break;
  1182. case SRB_STATUS_REQUEST_FLUSHED:
  1183. case SRB_STATUS_ERROR:
  1184. case SRB_STATUS_INVALID_REQUEST:
  1185. case SRB_STATUS_REQUEST_SENSE_FAILED:
  1186. case SRB_STATUS_NO_HBA:
  1187. case SRB_STATUS_UNEXPECTED_BUS_FREE:
  1188. case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
  1189. case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
  1190. case SRB_STATUS_DELAYED_RETRY:
  1191. case SRB_STATUS_BAD_FUNCTION:
  1192. case SRB_STATUS_NOT_STARTED:
  1193. case SRB_STATUS_NOT_IN_USE:
  1194. case SRB_STATUS_FORCE_ABORT:
  1195. case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
  1196. default:
  1197. #ifdef AAC_DETAILED_STATUS_INFO
  1198. printk("aacraid: SRB ERROR (%s)n",aac_get_status_string(le32_to_cpu(srbreply->srb_status)));
  1199. #endif
  1200. scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
  1201. break;
  1202. }
  1203. if (le32_to_cpu(srbreply->scsi_status) == 0x02 ){  // Check Condition
  1204. int len;
  1205. len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))?
  1206. sizeof(scsicmd->sense_buffer):srbreply->sense_data_size;
  1207. printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%dn", le32_to_cpu(srbreply->status), len);
  1208. memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
  1209. }
  1210. /*
  1211.  * OR in the scsi status (already shifted up a bit)
  1212.  */
  1213. scsicmd->result |= le32_to_cpu(srbreply->scsi_status);
  1214. fib_complete(fibptr);
  1215. fib_free(fibptr);
  1216. aac_io_done(scsicmd);
  1217. }
  1218. /**
  1219.  *
  1220.  * aac_send_scb_fib
  1221.  * @scsicmd: the scsi command block
  1222.  *
  1223.  * This routine will form a FIB and fill in the aac_srb from the 
  1224.  * scsicmd passed in.
  1225.  */
  1226. static int aac_send_srb_fib(Scsi_Cmnd* scsicmd)
  1227. {
  1228. struct fib* cmd_fibcontext;
  1229. struct aac_dev* dev;
  1230. int status;
  1231. struct aac_srb *srbcmd;
  1232. u16 fibsize;
  1233. u32 flag;
  1234. if( scsicmd->target > 15 || scsicmd->lun > 7) {
  1235. scsicmd->result = DID_NO_CONNECT << 16;
  1236. __aac_io_done(scsicmd);
  1237. return 0;
  1238. }
  1239. dev = (struct aac_dev *)scsicmd->host->hostdata;
  1240. switch(scsicmd->sc_data_direction){
  1241. case SCSI_DATA_WRITE:
  1242. flag = SRB_DataOut;
  1243. break;
  1244. case SCSI_DATA_UNKNOWN:  
  1245. flag = SRB_DataIn | SRB_DataOut;
  1246. break;
  1247. case SCSI_DATA_READ:
  1248. flag = SRB_DataIn;
  1249. break;
  1250. case SCSI_DATA_NONE: 
  1251. default:
  1252. flag = SRB_NoDataXfer;
  1253. break;
  1254. }
  1255. /*
  1256.  * Allocate and initialize a Fib then setup a BlockWrite command
  1257.  */
  1258. if (!(cmd_fibcontext = fib_alloc(dev))) {
  1259. scsicmd->result = DID_ERROR << 16;
  1260. __aac_io_done(scsicmd);
  1261. return -1;
  1262. }
  1263. fib_init(cmd_fibcontext);
  1264. srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
  1265. srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
  1266. srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scsicmd->channel));
  1267. srbcmd->target   = cpu_to_le32(scsicmd->target);
  1268. srbcmd->lun      = cpu_to_le32(scsicmd->lun);
  1269. srbcmd->flags    = cpu_to_le32(flag);
  1270. srbcmd->timeout  = cpu_to_le32(0);  // timeout not used
  1271. srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
  1272. srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len);
  1273. if( dev->pae_support ==1 ) {
  1274. aac_build_sg64(scsicmd, (struct sgmap64*) &srbcmd->sg);
  1275. srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
  1276. memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
  1277. memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
  1278. /*
  1279.  * Build Scatter/Gather list
  1280.  */
  1281. fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
  1282. /*
  1283.  * Now send the Fib to the adapter
  1284.  */
  1285. status = fib_send(ScsiPortCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
  1286.   (fib_callback) aac_srb_callback, (void *) scsicmd);
  1287. } else {
  1288. aac_build_sg(scsicmd, (struct sgmap*)&srbcmd->sg);
  1289. srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
  1290. memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
  1291. memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
  1292. /*
  1293.  * Build Scatter/Gather list
  1294.  */
  1295. fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
  1296. /*
  1297.  * Now send the Fib to the adapter
  1298.  */
  1299. status = fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
  1300.   (fib_callback) aac_srb_callback, (void *) scsicmd);
  1301. }
  1302. /*
  1303.  * Check that the command queued to the controller
  1304.  */
  1305. if (status == -EINPROGRESS){
  1306. return 0;
  1307. }
  1308. printk(KERN_WARNING "aac_srb: fib_send failed with status: %dn", status);
  1309. /*
  1310.  * For some reason, the Fib didn't queue, return QUEUE_FULL
  1311.  */
  1312. scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;
  1313. __aac_io_done(scsicmd);
  1314. fib_complete(cmd_fibcontext);
  1315. fib_free(cmd_fibcontext);
  1316. return -1;
  1317. }
  1318. static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* psg)
  1319. {
  1320. struct aac_dev *dev;
  1321. unsigned long byte_count = 0;
  1322. dev = (struct aac_dev *)scsicmd->host->hostdata;
  1323. // Get rid of old data
  1324. psg->count = cpu_to_le32(0);
  1325. psg->sg[0].addr = cpu_to_le32(NULL);
  1326. psg->sg[0].count = cpu_to_le32(0);  
  1327. if (scsicmd->use_sg) {
  1328. struct scatterlist *sg;
  1329. int i;
  1330. int sg_count;
  1331. sg = (struct scatterlist *) scsicmd->request_buffer;
  1332. sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
  1333. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1334. psg->count = cpu_to_le32(sg_count);
  1335. byte_count = 0;
  1336. for (i = 0; i < sg_count; i++) {
  1337. psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
  1338. psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
  1339. byte_count += sg_dma_len(sg);
  1340. sg++;
  1341. }
  1342. /* hba wants the size to be exact */
  1343. if(byte_count > scsicmd->request_bufflen){
  1344. psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
  1345. byte_count = scsicmd->request_bufflen;
  1346. }
  1347. /* Check for command underflow */
  1348. if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
  1349. printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08Xn",
  1350. byte_count, scsicmd->underflow);
  1351. }
  1352. }
  1353. else if(scsicmd->request_bufflen) {
  1354. dma_addr_t addr; 
  1355. addr = pci_map_single(dev->pdev,
  1356. scsicmd->request_buffer,
  1357. scsicmd->request_bufflen,
  1358. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1359. psg->count = cpu_to_le32(1);
  1360. psg->sg[0].addr = cpu_to_le32(addr);
  1361. psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
  1362. scsicmd->SCp.ptr = (void *)addr;
  1363. byte_count = scsicmd->request_bufflen;
  1364. }
  1365. return byte_count;
  1366. }
  1367. static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg)
  1368. {
  1369. struct aac_dev *dev;
  1370. unsigned long byte_count = 0;
  1371. u64 le_addr;
  1372. dev = (struct aac_dev *)scsicmd->host->hostdata;
  1373. // Get rid of old data
  1374. psg->count = cpu_to_le32(0);
  1375. psg->sg[0].addr[0] = cpu_to_le32(NULL);
  1376. psg->sg[0].addr[1] = cpu_to_le32(NULL);
  1377. psg->sg[0].count = cpu_to_le32(0);  
  1378. if (scsicmd->use_sg) {
  1379. struct scatterlist *sg;
  1380. int i;
  1381. int sg_count;
  1382. sg = (struct scatterlist *) scsicmd->request_buffer;
  1383. sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
  1384. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1385. psg->count = cpu_to_le32(sg_count);
  1386. byte_count = 0;
  1387. for (i = 0; i < sg_count; i++) {
  1388. le_addr = cpu_to_le64(sg_dma_address(sg));
  1389. psg->sg[i].addr[1] = (u32)(le_addr>>32);
  1390. psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
  1391. psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
  1392. byte_count += sg_dma_len(sg);
  1393. sg++;
  1394. }
  1395. /* hba wants the size to be exact */
  1396. if(byte_count > scsicmd->request_bufflen){
  1397. psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
  1398. byte_count = scsicmd->request_bufflen;
  1399. }
  1400. /* Check for command underflow */
  1401. if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
  1402. printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08Xn",
  1403. byte_count, scsicmd->underflow);
  1404. }
  1405. }
  1406. else if(scsicmd->request_bufflen) {
  1407. dma_addr_t addr; 
  1408. addr = pci_map_single(dev->pdev,
  1409. scsicmd->request_buffer,
  1410. scsicmd->request_bufflen,
  1411. scsi_to_pci_dma_dir(scsicmd->sc_data_direction));
  1412. psg->count = cpu_to_le32(1);
  1413. le_addr = cpu_to_le64(addr);
  1414. psg->sg[0].addr[1] = (u32)(le_addr>>32);
  1415. psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
  1416. psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
  1417. scsicmd->SCp.ptr = (void *)addr;
  1418. byte_count = scsicmd->request_bufflen;
  1419. }
  1420. return byte_count;
  1421. }
  1422. #ifdef AAC_DETAILED_STATUS_INFO
  1423. struct aac_srb_status_info {
  1424. u32 status;
  1425. char *str;
  1426. };
  1427. static struct aac_srb_status_info srb_status_info[] = {
  1428. { SRB_STATUS_PENDING, "Pending Status"},
  1429. { SRB_STATUS_SUCCESS, "Success"},
  1430. { SRB_STATUS_ABORTED, "Aborted Command"},
  1431. { SRB_STATUS_ABORT_FAILED, "Abort Failed"},
  1432. { SRB_STATUS_ERROR, "Error Event"}, 
  1433. { SRB_STATUS_BUSY, "Device Busy"},
  1434. { SRB_STATUS_INVALID_REQUEST, "Invalid Request"},
  1435. { SRB_STATUS_INVALID_PATH_ID, "Invalid Path ID"},
  1436. { SRB_STATUS_NO_DEVICE, "No Device"},
  1437. { SRB_STATUS_TIMEOUT, "Timeout"},
  1438. { SRB_STATUS_SELECTION_TIMEOUT, "Selection Timeout"},
  1439. { SRB_STATUS_COMMAND_TIMEOUT, "Command Timeout"},
  1440. { SRB_STATUS_MESSAGE_REJECTED, "Message Rejected"},
  1441. { SRB_STATUS_BUS_RESET, "Bus Reset"},
  1442. { SRB_STATUS_PARITY_ERROR, "Parity Error"},
  1443. { SRB_STATUS_REQUEST_SENSE_FAILED,"Request Sense Failed"},
  1444. { SRB_STATUS_NO_HBA, "No HBA"},
  1445. { SRB_STATUS_DATA_OVERRUN, "Data Overrun/Data Underrun"},
  1446. { SRB_STATUS_UNEXPECTED_BUS_FREE,"Unexpected Bus Free"},
  1447. { SRB_STATUS_PHASE_SEQUENCE_FAILURE,"Phase Error"},
  1448. { SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},
  1449. { SRB_STATUS_REQUEST_FLUSHED, "Request Flushed"},
  1450. { SRB_STATUS_DELAYED_RETRY, "Delayed Retry"},
  1451. { SRB_STATUS_INVALID_LUN, "Invalid LUN"}, 
  1452. { SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"},
  1453. { SRB_STATUS_BAD_FUNCTION, "Bad Function"},
  1454. { SRB_STATUS_ERROR_RECOVERY, "Error Recovery"},
  1455. { SRB_STATUS_NOT_STARTED, "Not Started"},
  1456. { SRB_STATUS_NOT_IN_USE, "Not In Use"},
  1457.      { SRB_STATUS_FORCE_ABORT, "Force Abort"},
  1458. { SRB_STATUS_DOMAIN_VALIDATION_FAIL,"Domain Validation Failure"},
  1459. { 0xff, "Unknown Error"}
  1460. };
  1461. char *aac_get_status_string(u32 status)
  1462. {
  1463. int i;
  1464. for(i=0; i < (sizeof(srb_status_info)/sizeof(struct aac_srb_status_info)); i++ ){
  1465. if(srb_status_info[i].status == status){
  1466. return srb_status_info[i].str;
  1467. }
  1468. }
  1469. return "Bad Status Code";
  1470. }
  1471. #endif