linit.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:21k
源码类别:

嵌入式Linux

开发平台:

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.  *
  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.  *   linit.c
  26.  *
  27.  * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
  28.  *
  29.  * Provides the following driver entry points:
  30.  * aac_detect()
  31.  * aac_release()
  32.  * aac_queuecommand()
  33.  * aac_resetcommand()
  34.  * aac_biosparm()
  35.  *
  36.  */
  37. #define AAC_DRIVER_VERSION "0.9.9ac2-rel"
  38. #define AAC_DRIVER_BUILD_DATE __DATE__
  39. #include <linux/module.h>
  40. #include <linux/config.h>
  41. #include <linux/kernel.h>
  42. #include <linux/init.h>
  43. #include <linux/types.h>
  44. #include <linux/sched.h>
  45. #include <linux/pci.h>
  46. #include <linux/spinlock.h>
  47. #include <linux/slab.h>
  48. #include <linux/completion.h>
  49. #include <asm/semaphore.h>
  50. #include <linux/blk.h>
  51. #include "scsi.h"
  52. #include "hosts.h"
  53. #include "aacraid.h"
  54. #include "sd.h"
  55. #define AAC_DRIVERNAME "aacraid"
  56. MODULE_AUTHOR("Red Hat Inc and Adaptec OEM RAID Solutions");
  57. MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, and HP NetRAID-4M devices.  http://domsch.com/linux/");
  58. MODULE_LICENSE("GPL");
  59. struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS];
  60. static unsigned aac_count = 0;
  61. static int aac_cfg_major = -1;
  62. static int single_command_done = 0;
  63. /*
  64.  * Because of the way Linux names scsi devices, the order in this table has
  65.  * become important.  Check for on-board Raid first, add-in cards second.
  66.  */
  67. /* FIXME static */struct aac_driver_ident aac_drivers[] = {
  68. { 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 2/Si */
  69. { 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  70. { 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
  71. { 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Si */
  72. { 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  73. { 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  74. { 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  75. { 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  76. { 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL    ", "PERCRAID        " }, /* PERC 3/Di */
  77. { 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL    ", "PERCRAID        " }, /* Dell PERC2 "Quad Channel" */
  78. { 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   " }, /* Adaptec 5400S */
  79. { 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid",  "HP      ", "NetRAID-4M      " }  /* HP NetRAID-4M */
  80. };
  81. #define NUM_AACTYPES (sizeof(aac_drivers) / sizeof(struct aac_driver_ident))
  82. static int num_aacdrivers = NUM_AACTYPES;
  83. static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
  84. static int aac_cfg_open(struct inode * inode, struct file * file);
  85. static int aac_cfg_release(struct inode * inode,struct file * file);
  86. static struct file_operations aac_cfg_fops = {
  87. owner: THIS_MODULE,
  88. ioctl: aac_cfg_ioctl,
  89. open: aac_cfg_open,
  90. release: aac_cfg_release
  91. };
  92. static int aac_detect(Scsi_Host_Template *);
  93. static int aac_release(struct Scsi_Host *);
  94. static int aac_queuecommand(Scsi_Cmnd *, void (*CompletionRoutine)(Scsi_Cmnd *));
  95. static int aac_command(Scsi_Cmnd *);
  96. static int aac_abortcommand(Scsi_Cmnd *scsi_cmnd_ptr);
  97. static int aac_resetcommand(Scsi_Cmnd *, unsigned int);
  98. static int aac_biosparm(Scsi_Disk *, kdev_t, int *);
  99. static int aac_procinfo(char *, char **, off_t, int, int, int);
  100. static int aac_ioctl(Scsi_Device *, int, void *);
  101. static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
  102. /**
  103.  * aac_detect - Probe for aacraid cards
  104.  * @template: SCSI driver template
  105.  *
  106.  * Probe for AAC Host Adapters initialize, register, and report the 
  107.  * configuration of each AAC Host Adapter found.
  108.  * Returns the number of adapters successfully initialized and 
  109.  * registered.
  110.  * Initializes all data necessary for this particular SCSI driver.
  111.  * Notes:
  112.  * The detect routine must not call any of the mid level functions 
  113.  * to queue commands because things are not guaranteed to be set 
  114.  * up yet. The detect routine can send commands to the host adapter 
  115.  * as long as the program control will not be passed to scsi.c in 
  116.  * the processing of the command. Note especially that 
  117.  * scsi_malloc/scsi_free must not be called.
  118.  *
  119.  */
  120.  
  121. static int aac_detect(Scsi_Host_Template *template)
  122. {
  123. int index;
  124. int container;
  125. u16 vendor_id, device_id;
  126. struct Scsi_Host *host_ptr;
  127. struct pci_dev *dev = NULL;
  128. struct aac_dev *aac;
  129. struct fsa_scsi_hba *fsa_dev_ptr;
  130. char *name = NULL;
  131. printk(KERN_INFO "Red Hat/Adaptec aacraid driver, %sn", AAC_DRIVER_BUILD_DATE);
  132. /* setting up the proc directory structure */
  133. template->proc_name = "aacraid";
  134. for( index = 0; index != num_aacdrivers; index++ )
  135. {
  136. device_id = aac_drivers[index].device;
  137. vendor_id = aac_drivers[index].vendor;
  138. name = aac_drivers[index].name;
  139. dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.n", 
  140. name, vendor_id, device_id,
  141. aac_drivers[index].subsystem_vendor,
  142. aac_drivers[index].subsystem_device));
  143. dev = NULL;
  144. while((dev = pci_find_device(vendor_id, device_id, dev)))
  145. {
  146. if (pci_enable_device(dev))
  147. continue;
  148. pci_set_master(dev);
  149. pci_set_dma_mask(dev, 0xFFFFFFFFULL);
  150. if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) || 
  151.    (dev->subsystem_device != aac_drivers[index].subsystem_device))
  152. continue;
  153. dprintk((KERN_DEBUG "%s device detected.n", name));
  154. dprintk((KERN_DEBUG "%x/%x/%x/%x.n", vendor_id, device_id, 
  155. aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device));
  156. /* Increment the host adapter count */
  157. aac_count++;
  158. /*
  159.  * scsi_register() allocates memory for a Scsi_Hosts structure and
  160.  * links it into the linked list of host adapters. This linked list
  161.  * contains the data for all possible <supported> scsi hosts.
  162.  * This is similar to the Scsi_Host_Template, except that we have
  163.  * one entry for each actual physical host adapter on the system,
  164.  * stored as a linked list. If there are two AAC boards, then we
  165.  * will need to make two Scsi_Host entries, but there will be only
  166.  * one Scsi_Host_Template entry. The second argument to scsi_register()
  167.  * specifies the size of the extra memory we want to hold any device 
  168.  * specific information.
  169.  */
  170. host_ptr = scsi_register( template, sizeof(struct aac_dev) );
  171. /* 
  172.  * These three parameters can be used to allow for wide SCSI 
  173.  * and for host adapters that support multiple buses.
  174.  */
  175. host_ptr->max_id = 17;
  176. host_ptr->max_lun = 8;
  177. host_ptr->max_channel = 1;
  178. host_ptr->irq = dev->irq; /* Adapter IRQ number */
  179. /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
  180. host_ptr->base = dev->resource[0].start;
  181. scsi_set_pci_device(host_ptr, dev);
  182. dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].n", host_ptr->base, dev->resource[0].start));
  183. dprintk((KERN_DEBUG "Device irq = 0x%x.n", dev->irq));
  184. /*
  185.  * The unique_id field is a unique identifier that must
  186.  * be assigned so that we have some way of identifying
  187.  * each host adapter properly and uniquely. For hosts 
  188.  * that do not support more than one card in the
  189.  * system, this does not need to be set. It is
  190.  * initialized to zero in scsi_register(). This is the 
  191.  * value returned as aac->id.
  192.  */
  193. host_ptr->unique_id = aac_count - 1;
  194. /*
  195.  * This function is called after the device list has
  196.  * been built to find the tagged queueing depth 
  197.  * supported for each device.
  198.  */
  199. host_ptr->select_queue_depths = aac_queuedepth;
  200. aac = (struct aac_dev *)host_ptr->hostdata;
  201. /* attach a pointer back to Scsi_Host */
  202. aac->scsi_host_ptr = host_ptr;
  203. aac->pdev = dev;
  204. aac->cardtype =  index;
  205. aac->name = aac->scsi_host_ptr->hostt->name;
  206. aac->id = aac->scsi_host_ptr->unique_id;
  207. /* Initialize the ordinal number of the device to -1 */
  208. fsa_dev_ptr = &(aac->fsa_dev);
  209. for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
  210. fsa_dev_ptr->devno[container] = -1;
  211. dprintk((KERN_DEBUG "Initializing Hardware...n"));
  212. if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
  213. {
  214. /* device initialization failed */
  215. printk(KERN_WARNING "aacraid: device initialization failed.n");
  216. scsi_unregister(host_ptr);
  217. aac_count--;
  218. else
  219. {
  220. dprintk((KERN_DEBUG "%s:%d device initialization successful.n", name, host_ptr->unique_id));
  221. aac_get_containers(aac);
  222. aac_devices[aac_count-1] = aac;
  223. }
  224. }
  225. }
  226. if( aac_count ){
  227. if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
  228. printk(KERN_WARNING "aacraid: unable to register "aac" device.n");
  229. }
  230. template->present = aac_count; /* # of cards of this type found */
  231. return aac_count;
  232. }
  233. /**
  234.  * aac_release - release SCSI host resources
  235.  * @host_ptr: SCSI host to clean up
  236.  *
  237.  * Release all resources previously acquired to support a specific Host 
  238.  * Adapter and unregister the AAC Host Adapter.
  239.  *
  240.  * BUGS: Does not wait for the thread it kills to die.
  241.  */
  242. static int aac_release(struct Scsi_Host *host_ptr)
  243. {
  244. struct aac_dev *dev;
  245. dprintk((KERN_DEBUG "aac_release.n"));
  246. dev = (struct aac_dev *)host_ptr->hostdata;
  247. /*
  248.  * kill any threads we started
  249.  */
  250. kill_proc(dev->thread_pid, SIGKILL, 0);
  251. wait_for_completion(&dev->aif_completion);
  252. /*
  253.  * Call the comm layer to detach from this adapter
  254.  */
  255. aac_detach(dev);
  256. /* Check free orderings... */
  257. /* remove interrupt binding */
  258. free_irq(host_ptr->irq, dev);
  259. iounmap((void * )dev->regs.sa);
  260. /* unregister adapter */
  261. scsi_unregister(host_ptr);
  262. /*
  263.  * FIXME: This assumes no hot plugging is going on...
  264.  */
  265. if( aac_cfg_major >= 0 )
  266. {
  267. unregister_chrdev(aac_cfg_major, "aac");
  268. aac_cfg_major = -1;
  269. }
  270. return 0;
  271. }
  272. /**
  273.  * aac_queuecommand - queue a SCSI command
  274.  * @scsi_cmnd_ptr: SCSI command to queue
  275.  * @CompletionRoutine: Function to call on command completion
  276.  *
  277.  * Queues a command for execution by the associated Host Adapter.
  278.  */ 
  279. static int aac_queuecommand(Scsi_Cmnd *scsi_cmnd_ptr, void (*CompletionRoutine)(Scsi_Cmnd *))
  280. {
  281. int ret;
  282. scsi_cmnd_ptr->scsi_done = CompletionRoutine;
  283. /*
  284.  * aac_scsi_cmd() handles command processing, setting the 
  285.  * result code and calling completion routine. 
  286.  */
  287. if((ret = aac_scsi_cmd(scsi_cmnd_ptr)) != 0)
  288. dprintk((KERN_DEBUG "aac_scsi_cmd failed.n"));
  289. return ret;
  290. /**
  291.  * aac_done - Callback function for a non-queued command.
  292.  * @scsi_cmnd_ptr: SCSI command block to wait for
  293.  *
  294.  * Sets single_command done to 1. This lets aac_command complete. 
  295.  * This function is obsolete.
  296.  *
  297.  * Bugs: Doesn't actually work properly with multiple controllers
  298.  */
  299.  
  300. static void aac_done(Scsi_Cmnd * scsi_cmnd_ptr) 
  301. {
  302. single_command_done = 1;
  303. }
  304. /**
  305.  * aac_command - synchronous SCSI command execution
  306.  * @scsi_cmnd_ptr: SCSI command to issue
  307.  *
  308.  * Accepts a single command for execution by the associated Host Adapter.
  309.  * Waits until it completes an then returns an int where:
  310.  * Byte 0 = SCSI status code
  311.  * Byte 1 = SCSI 1 byte message
  312.  * Byte 2 = host error return
  313.  * Byte 3 = mid level error return
  314.  */
  315.  
  316. static int aac_command(Scsi_Cmnd *scsi_cmnd_ptr )
  317. {
  318. scsi_cmnd_ptr->scsi_done = aac_done;
  319. dprintk((KERN_DEBUG "aac_command.n"));
  320. /*
  321.  * aac_scsi_cmd() handles command processing, setting the 
  322.  * result code and calling completion routine.
  323.  */
  324. single_command_done = 0;
  325. aac_scsi_cmd(scsi_cmnd_ptr);
  326. while(!single_command_done)
  327. rmb();
  328. return scsi_cmnd_ptr->result;
  329. /**
  330.  * aac_abortcommand - Abort command if possible.
  331.  * @scsi_cmnd_ptr: SCSI command block to abort
  332.  *
  333.  * Called when the midlayer wishes to abort a command. We don't support
  334.  * this facility, and our firmware looks after life for us. We just
  335.  * report the command as busy. 
  336.  */
  337.  
  338. static int aac_abortcommand(Scsi_Cmnd *scsi_cmnd_ptr )
  339. {
  340. return SCSI_ABORT_BUSY;
  341. }
  342. /**
  343.  * aac_resetcommand - Reset command handling
  344.  * @scsi_cmnd_ptr: SCSI command block causing the reset
  345.  * @reset_flags: Reset hints from the midlayer code
  346.  *
  347.  * Issue a reset of a SCSI command. We are ourselves not truely a SCSI
  348.  * controller and our firmware will do the work for us anyway. Thus this
  349.  * is a no-op. We just return SCSI_RESET_PUNT
  350.  */
  351.  
  352. static int aac_resetcommand(struct scsi_cmnd *scsi_cmnd_ptr, unsigned int reset_flags )
  353. {
  354. return SCSI_RESET_PUNT;
  355. }
  356. /**
  357.  * aac_driverinfo - Returns the host adapter name
  358.  * @host_ptr: Scsi host to report on
  359.  *
  360.  * Returns a static string describing the device in question
  361.  */
  362. const char *aac_driverinfo(struct Scsi_Host *host_ptr)
  363. {
  364. struct aac_dev *dev = (struct aac_dev *)host_ptr->hostdata;
  365. return aac_drivers[dev->cardtype].name;
  366. }
  367. /**
  368.  * aac_biosparm - return BIOS parameters for disk
  369.  * @disk: SCSI disk object to process
  370.  * @device: kdev_t of the disk in question
  371.  * @geom: geometry block to fill in
  372.  *
  373.  * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.  
  374.  * The default disk geometry is 64 heads, 32 sectors, and the appropriate 
  375.  * number of cylinders so as not to exceed drive capacity.  In order for 
  376.  * disks equal to or larger than 1 GB to be addressable by the BIOS
  377.  * without exceeding the BIOS limitation of 1024 cylinders, Extended 
  378.  * Translation should be enabled.   With Extended Translation enabled, 
  379.  * drives between 1 GB inclusive and 2 GB exclusive are given a disk 
  380.  * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive 
  381.  * are given a disk geometry of 255 heads and 63 sectors.  However, if 
  382.  * the BIOS detects that the Extended Translation setting does not match 
  383.  * the geometry in the partition table, then the translation inferred 
  384.  * from the partition table will be used by the BIOS, and a warning may 
  385.  * be displayed.
  386.  */
  387.  
  388. static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
  389. {
  390. struct diskparm *param = (struct diskparm *)geom;
  391. struct buffer_head * buf;
  392. dprintk((KERN_DEBUG "aac_biosparm.n"));
  393. /*
  394.  * Assuming extended translation is enabled - #REVISIT#
  395.  */
  396. if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
  397. {
  398. if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
  399. {
  400. param->heads = 255;
  401. param->sectors = 63;
  402. }
  403. else
  404. {
  405. param->heads = 128;
  406. param->sectors = 32;
  407. }
  408. }
  409. else
  410. {
  411. param->heads = 64;
  412. param->sectors = 32;
  413. }
  414. param->cylinders = disk->capacity/(param->heads * param->sectors);
  415. /*
  416.  * Read the first 1024 bytes from the disk device
  417.  */
  418. buf = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, block_size(dev));
  419. if(buf == NULL)
  420. return 0;
  421. /* 
  422.  * If the boot sector partition table is valid, search for a partition 
  423.  * table entry whose end_head matches one of the standard geometry 
  424.  * translations ( 64/32, 128/32, 255/63 ).
  425.  */
  426.  
  427. if(*(unsigned short *)(buf->b_data + 0x1fe) == cpu_to_le16(0xaa55))
  428. {
  429. struct partition *first = (struct partition * )(buf->b_data + 0x1be);
  430. struct partition *entry = first;
  431. int saved_cylinders = param->cylinders;
  432. int num;
  433. unsigned char end_head, end_sec;
  434. for(num = 0; num < 4; num++)
  435. {
  436. end_head = entry->end_head;
  437. end_sec = entry->end_sector & 0x3f;
  438. if(end_head == 63)
  439. {
  440. param->heads = 64;
  441. param->sectors = 32;
  442. break;
  443. }
  444. else if(end_head == 127)
  445. {
  446. param->heads = 128;
  447. param->sectors = 32;
  448. break;
  449. }
  450. else if(end_head == 254) 
  451. {
  452. param->heads = 255;
  453. param->sectors = 63;
  454. break;
  455. }
  456. entry++;
  457. }
  458. if(num == 4)
  459. {
  460. end_head = first->end_head;
  461. end_sec = first->end_sector & 0x3f;
  462. }
  463. param->cylinders = disk->capacity / (param->heads * param->sectors);
  464. if(num < 4 && end_sec == param->sectors)
  465. {
  466. if(param->cylinders != saved_cylinders)
  467. dprintk((KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.n",
  468. param->heads, param->sectors, num));
  469. }
  470. else if(end_head > 0 || end_sec > 0)
  471. {
  472. dprintk((KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.n",
  473. end_head + 1, end_sec, num));
  474. dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.n",
  475. param->heads, param->sectors));
  476. }
  477. }
  478. brelse(buf);
  479. return 0;
  480. }
  481. /**
  482.  * aac_queuedepth - compute queue depths
  483.  * @host: SCSI host in question
  484.  * @dev: SCSI device we are considering
  485.  *
  486.  * Selects queue depths for each target device based on the host adapter's
  487.  * total capacity and the queue depth supported by the target device.
  488.  * A queue depth of one automatically disables tagged queueing.
  489.  */
  490. static void aac_queuedepth(struct Scsi_Host * host, Scsi_Device * dev )
  491. {
  492. Scsi_Device * dptr;
  493. dprintk((KERN_DEBUG "aac_queuedepth.n"));
  494. dprintk((KERN_DEBUG "Device #   Q Depth   Onlinen"));
  495. dprintk((KERN_DEBUG "---------------------------n"));
  496. for(dptr = dev; dptr != NULL; dptr = dptr->next)
  497. {
  498. if(dptr->host == host)
  499. {
  500. dptr->queue_depth = 10;
  501. dprintk((KERN_DEBUG "  %2d         %d        %dn", 
  502. dptr->id, dptr->queue_depth, dptr->online));
  503. }
  504. }
  505. }
  506. /*------------------------------------------------------------------------------
  507. aac_ioctl()
  508. Handle SCSI ioctls
  509.  *----------------------------------------------------------------------------*/
  510. static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
  511. /*----------------------------------------------------------------------------*/
  512. {
  513. struct aac_dev *dev;
  514. dprintk((KERN_DEBUG "aac_ioctl.n"));
  515. dev = (struct aac_dev *)scsi_dev_ptr->host->hostdata;
  516. return aac_do_ioctl(dev, cmd, arg);
  517. }
  518. /**
  519.  * aac_cfg_open - open a configuration file
  520.  * @inode: inode being opened
  521.  * @file: file handle attached
  522.  *
  523.  * Called when the configuration device is opened. Does the needed
  524.  * set up on the handle and then returns
  525.  *
  526.  * Bugs: This needs extending to check a given adapter is present
  527.  * so we can support hot plugging, and to ref count adapters.
  528.  */
  529. static int aac_cfg_open(struct inode * inode, struct file * file )
  530. {
  531. unsigned minor_number = MINOR(inode->i_rdev);
  532. if(minor_number >= aac_count)
  533. return -ENODEV;
  534. return 0;
  535. }
  536. /**
  537.  * aac_cfg_release - close down an AAC config device
  538.  * @inode: inode of configuration file
  539.  * @file: file handle of configuration file
  540.  *
  541.  * Called when the last close of the configuration file handle
  542.  * is performed.
  543.  */
  544.  
  545. static int aac_cfg_release(struct inode * inode, struct file * file )
  546. {
  547. return 0;
  548. }
  549. /**
  550.  * aac_cfg_ioctl - AAC configuration request
  551.  * @inode: inode of device
  552.  * @file: file handle
  553.  * @cmd: ioctl command code
  554.  * @arg: argument
  555.  *
  556.  * Handles a configuration ioctl. Currently this involves wrapping it
  557.  * up and feeding it into the nasty windowsalike glue layer.
  558.  *
  559.  * Bugs: Needs locking against parallel ioctls lower down
  560.  * Bugs: Needs to handle hot plugging
  561.  */
  562.  
  563. static int aac_cfg_ioctl(struct inode * inode,  struct file * file, unsigned int cmd, unsigned long arg )
  564. {
  565. struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
  566. return aac_do_ioctl(dev, cmd, (void *)arg);
  567. }
  568. /*
  569.  * To use the low level SCSI driver support using the linux kernel loadable 
  570.  * module interface we should initialize the global variable driver_interface  
  571.  * (datatype Scsi_Host_Template) and then include the file scsi_module.c.
  572.  */
  573.  
  574. static Scsi_Host_Template driver_template = {
  575. module: THIS_MODULE,
  576. name:            "AAC",
  577. proc_info:       aac_procinfo,
  578. detect:          aac_detect,
  579. release:         aac_release,
  580. info:            aac_driverinfo,
  581. ioctl:           aac_ioctl,
  582. command:         aac_command,
  583. queuecommand:    aac_queuecommand,
  584. abort:           aac_abortcommand,
  585. reset:           aac_resetcommand,
  586. bios_param:      aac_biosparm,
  587. can_queue:       AAC_NUM_IO_FIB,
  588. this_id:         16,
  589. sg_tablesize:    16,
  590. max_sectors:     128,
  591. cmd_per_lun:     1,
  592. eh_abort_handler:       aac_abortcommand,
  593. use_clustering: ENABLE_CLUSTERING,
  594. };
  595. #include "scsi_module.c"
  596. /**
  597.  * aac_procinfo - Implement /proc/scsi/<drivername>/<n>
  598.  * @proc_buffer: memory buffer for I/O
  599.  * @start_ptr: pointer to first valid data
  600.  * @offset: offset into file
  601.  * @bytes_available: space left
  602.  * @host_no: scsi host ident
  603.  * @write: direction of I/O
  604.  *
  605.  * Used to export driver statistics and other infos to the world outside 
  606.  * the kernel using the proc file system. Also provides an interface to
  607.  * feed the driver with information.
  608.  *
  609.  * For reads
  610.  * - if offset > 0 return 0
  611.  * - if offset == 0 write data to proc_buffer and set the start_ptr to
  612.  * beginning of proc_buffer, return the number of characters written.
  613.  * For writes
  614.  * - writes currently not supported, return 0
  615.  *
  616.  * Bugs: Only offset zero is handled
  617.  */
  618. static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
  619. int bytes_available, int host_no, int write)
  620. {
  621. if(write || offset > 0)
  622. return 0;
  623. *start_ptr = proc_buffer;
  624. return sprintf(proc_buffer, "%s  %dn", "Raid Controller, scsi hba number", host_no);
  625. }
  626. EXPORT_NO_SYMBOLS;