ia64/xen-unstable

view xen/drivers/scsi/aacraid/linit.c @ 945:db2e1ea917df

bitkeeper revision 1.596.1.3 (3fb3b41eWUoRU0H8A0jEX5roXjxKkA)

Many files:
Greatly simplified Xen softirqs. They are now only executed in outermost Xen activation; they are never called within an irq context.
author kaf24@scramble.cl.cam.ac.uk
date Thu Nov 13 16:41:02 2003 +0000 (2003-11-13)
parents 3946af49a538
children 890460f07ddf
line source
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 */
38 #define AAC_DRIVER_VERSION "1.1.2"
39 #define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__
41 #include <linux/module.h>
42 #include <linux/config.h>
43 #include <linux/kernel.h>
44 #include <linux/init.h>
45 #include <linux/types.h>
46 #include <linux/sched.h>
47 #include <linux/pci.h>
48 #include <linux/spinlock.h>
49 #include <linux/slab.h>
50 /*#include <linux/completion.h>*/
51 /*#include <asm/semaphore.h>*/
52 #include <linux/blk.h>
53 #include "scsi.h"
54 #include "hosts.h"
56 #include "aacraid.h"
57 #include "sd.h"
59 #define AAC_DRIVERNAME "aacraid"
61 MODULE_AUTHOR("Red Hat Inc and Adaptec");
62 MODULE_DESCRIPTION("Supports Dell PERC2, 2/Si, 3/Si, 3/Di, Adaptec Advanced Raid Products, and HP NetRAID-4M devices. http://domsch.com/linux/ or http://linux.adaptec.com");
63 MODULE_LICENSE("GPL");
64 MODULE_PARM(paemode, "i");
65 MODULE_PARM_DESC(paemode, "Control whether dma addressing is using PAE. 0=off, 1=on");
67 #if 0
68 static int paemode = -1;
69 #endif
71 struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS];
73 static unsigned aac_count = 0;
74 static int aac_cfg_major = -1;
76 /*
77 * Because of the way Linux names scsi devices, the order in this table has
78 * become important. Check for on-board Raid first, add-in cards second.
79 *
80 * dmb - For now we add the number of channels to this structure.
81 * In the future we should add a fib that reports the number of channels
82 * for the card. At that time we can remove the channels from here
83 */
85 static struct aac_driver_ident aac_drivers[] = {
86 { 0x1028, 0x0001, 0x1028, 0x0001, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 2/Si (Iguana/PERC2Si) */
87 { 0x1028, 0x0002, 0x1028, 0x0002, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Opal/PERC3Di) */
88 { 0x1028, 0x0003, 0x1028, 0x0003, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
89 { 0x1028, 0x0004, 0x1028, 0x00d0, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
90 { 0x1028, 0x0002, 0x1028, 0x00d1, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Viper/PERC3DiV) */
91 { 0x1028, 0x0002, 0x1028, 0x00d9, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Lexus/PERC3DiL) */
92 { 0x1028, 0x000a, 0x1028, 0x0106, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
93 { 0x1028, 0x000a, 0x1028, 0x011b, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Dagger/PERC3DiD) */
94 { 0x1028, 0x000a, 0x1028, 0x0121, aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2 }, /* PERC 3/Di (Boxster/PERC3DiB) */
95 { 0x9005, 0x0283, 0x9005, 0x0283, aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2 }, /* catapult */
96 { 0x9005, 0x0284, 0x9005, 0x0284, aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2 }, /* tomcat */
97 { 0x9005, 0x0285, 0x9005, 0x0286, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT },/* Adaptec 2120S (Crusader) */
98 { 0x9005, 0x0285, 0x9005, 0x0285, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan) */
99 { 0x9005, 0x0285, 0x9005, 0x0287, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT },/* Adaptec 2200S (Vulcan-2m) */
100 { 0x9005, 0x0285, 0x17aa, 0x0286, aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1 }, /* Legend S220 (Legend Crusader) */
101 { 0x9005, 0x0285, 0x17aa, 0x0287, aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2 }, /* Legend S230 (Legend Vulcan) */
103 { 0x9005, 0x0285, 0x9005, 0x0288, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */
104 { 0x9005, 0x0285, 0x9005, 0x0289, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */
105 { 0x9005, 0x0285, 0x9005, 0x028a, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S PCI-X ZCR (Skyhawk) */
106 { 0x9005, 0x0285, 0x9005, 0x028b, aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S SO-DIMM PCI-X ZCR (Terminator) */
107 { 0x9005, 0x0285, 0x9005, 0x0290, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 2 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
108 { 0x9005, 0x0285, 0x1028, 0x0291, aac_rx_init, "aacraid", "DELL ", "CERC SATA RAID 2 ", 2 }, /* CERC SATA RAID 2 PCI SATA 8ch (DellCorsair) */
109 { 0x9005, 0x0285, 0x9005, 0x0292, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 2 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
110 { 0x9005, 0x0285, 0x9005, 0x0293, aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA ", 2 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
111 { 0x9005, 0x0285, 0x9005, 0x0294, aac_rx_init, "aacraid", "ADAPTEC ", "SO-DIMM SATA ZCR ", 2 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
112 /* ServeRAID */
113 /* { 0x9005, 0x0250, 0x1014, 0x0279, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Marco) */
114 /* { 0x9005, 0x0250, 0x1014, 0x028c, aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, */ /* (Sebring)*/
116 { 0x9005, 0x0285, 0x1028, 0x0287, aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2 }, /* Perc 320/DC*/
117 { 0x1011, 0x0046, 0x9005, 0x0365, aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/
118 { 0x1011, 0x0046, 0x9005, 0x0364, aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/
119 { 0x1011, 0x0046, 0x9005, 0x1364, aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4 }, /* Dell PERC2 "Quad Channel" */
120 { 0x1011, 0x0046, 0x103c, 0x10c2, aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4 } /* HP NetRAID-4M */
121 };
123 #define NUM_AACTYPES (sizeof(aac_drivers) / sizeof(struct aac_driver_ident))
124 static int num_aacdrivers = NUM_AACTYPES;
126 #if 0
127 static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
128 static int aac_cfg_open(struct inode * inode, struct file * file);
129 static int aac_cfg_release(struct inode * inode,struct file * file);
131 static struct file_operations aac_cfg_fops = {
132 owner: THIS_MODULE,
133 ioctl: aac_cfg_ioctl,
134 open: aac_cfg_open,
135 release: aac_cfg_release
136 };
137 #endif
139 static int aac_detect(Scsi_Host_Template *);
140 static int aac_release(struct Scsi_Host *);
141 static int aac_queuecommand(Scsi_Cmnd *, void (*CompletionRoutine)(Scsi_Cmnd *));
142 static int aac_biosparm(Scsi_Disk *, kdev_t, int *);
143 #ifdef CONFIG_PROC_FS
144 static int aac_procinfo(char *, char **, off_t, int, int, int);
145 #endif
146 static int aac_ioctl(Scsi_Device *, int, void *);
147 static int aac_eh_abort(Scsi_Cmnd * cmd);
148 static int aac_eh_device_reset(Scsi_Cmnd* cmd);
149 static int aac_eh_bus_reset(Scsi_Cmnd* cmd);
150 static int aac_eh_reset(Scsi_Cmnd* cmd);
152 static void aac_queuedepth(struct Scsi_Host *, Scsi_Device *);
154 /**
155 * aac_detect - Probe for aacraid cards
156 * @template: SCSI driver template
157 *
158 * Probe for AAC Host Adapters initialize, register, and report the
159 * configuration of each AAC Host Adapter found.
160 * Returns the number of adapters successfully initialized and
161 * registered.
162 * Initializes all data necessary for this particular SCSI driver.
163 * Notes:
164 * The detect routine must not call any of the mid level functions
165 * to queue commands because things are not guaranteed to be set
166 * up yet. The detect routine can send commands to the host adapter
167 * as long as the program control will not be passed to scsi.c in
168 * the processing of the command. Note especially that
169 * scsi_malloc/scsi_free must not be called.
170 *
171 */
173 static int aac_detect(Scsi_Host_Template *template)
174 {
175 int index;
176 int container;
177 u16 vendor_id, device_id;
178 struct Scsi_Host *host_ptr;
179 struct pci_dev *dev = NULL;
180 struct aac_dev *aac;
181 struct fsa_scsi_hba *fsa_dev_ptr;
182 char *name = NULL;
184 printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n", AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE);
186 /* setting up the proc directory structure */
187 template->proc_name = "aacraid";
188 spin_unlock_irq(&io_request_lock);
190 for( index = 0; index != num_aacdrivers; index++ )
191 {
192 device_id = aac_drivers[index].device;
193 vendor_id = aac_drivers[index].vendor;
194 name = aac_drivers[index].name;
195 dprintk((KERN_DEBUG "Checking %s %x/%x/%x/%x.\n",
196 name, vendor_id, device_id,
197 aac_drivers[index].subsystem_vendor,
198 aac_drivers[index].subsystem_device));
200 dev = NULL;
201 while((dev = pci_find_device(vendor_id, device_id, dev))) {
202 if (pci_enable_device(dev))
203 continue;
204 pci_set_master(dev);
206 if(aac_drivers[index].quirks & AAC_QUIRK_31BIT)
207 pci_set_dma_mask(dev, 0x7FFFFFFFULL);
208 else
209 pci_set_dma_mask(dev, 0xFFFFFFFFULL);
211 if((dev->subsystem_vendor != aac_drivers[index].subsystem_vendor) ||
212 (dev->subsystem_device != aac_drivers[index].subsystem_device))
213 continue;
215 dprintk((KERN_DEBUG "%s device detected.\n", name));
216 dprintk((KERN_DEBUG "%x/%x/%x/%x.\n", vendor_id, device_id,
217 aac_drivers[index].subsystem_vendor, aac_drivers[index].subsystem_device));
218 /*
219 * scsi_register() allocates memory for a Scsi_Hosts structure and
220 * links it into the linked list of host adapters. This linked list
221 * contains the data for all possible <supported> scsi hosts.
222 * This is similar to the Scsi_Host_Template, except that we have
223 * one entry for each actual physical host adapter on the system,
224 * stored as a linked list. If there are two AAC boards, then we
225 * will need to make two Scsi_Host entries, but there will be only
226 * one Scsi_Host_Template entry. The second argument to scsi_register()
227 * specifies the size of the extra memory we want to hold any device
228 * specific information.
229 */
230 host_ptr = scsi_register( template, sizeof(struct aac_dev) );
231 if(host_ptr == NULL)
232 continue;
233 /* Increment the host adapter count */
234 aac_count++;
235 /*
236 * These three parameters can be used to allow for wide SCSI
237 * and for host adapters that support multiple buses.
238 */
239 host_ptr->irq = dev->irq; /* Adapter IRQ number */
240 /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
241 host_ptr->base = dev->resource[0].start;
242 scsi_set_pci_device(host_ptr, dev);
243 dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].\n", host_ptr->base, dev->resource[0].start));
244 dprintk((KERN_DEBUG "Device irq = 0x%x.\n", dev->irq));
245 /*
246 * The unique_id field is a unique identifier that must
247 * be assigned so that we have some way of identifying
248 * each host adapter properly and uniquely. For hosts
249 * that do not support more than one card in the
250 * system, this does not need to be set. It is
251 * initialized to zero in scsi_register(). This is the
252 * value returned as aac->id.
253 */
254 host_ptr->unique_id = aac_count - 1;
255 /*
256 * This function is called after the device list has
257 * been built to find the tagged queueing depth
258 * supported for each device.
259 */
260 host_ptr->select_queue_depths = aac_queuedepth;
261 aac = (struct aac_dev *)host_ptr->hostdata;
262 /* attach a pointer back to Scsi_Host */
263 aac->scsi_host_ptr = host_ptr;
264 aac->pdev = dev;
265 aac->name = aac->scsi_host_ptr->hostt->name;
266 aac->id = aac->scsi_host_ptr->unique_id;
267 aac->cardtype = index;
269 aac->fibs = (struct fib*) kmalloc(sizeof(struct fib)*AAC_NUM_FIB, GFP_KERNEL);
270 spin_lock_init(&aac->fib_lock);
272 /* Initialize the ordinal number of the device to -1 */
273 fsa_dev_ptr = &(aac->fsa_dev);
274 for( container = 0; container < MAXIMUM_NUM_CONTAINERS; container++ )
275 fsa_dev_ptr->devno[container] = -1;
277 dprintk((KERN_DEBUG "Initializing Hardware...\n"));
278 if((*aac_drivers[index].init)(aac , host_ptr->unique_id) != 0)
279 {
280 /* device initialization failed */
281 printk(KERN_WARNING "aacraid: device initialization failed.\n");
282 scsi_unregister(host_ptr);
283 aac_count--;
284 continue;
285 }
286 dprintk((KERN_DEBUG "%s:%d device initialization successful.\n", name, host_ptr->unique_id));
287 aac_get_adapter_info(aac);
288 if(aac->nondasd_support == 1)
289 {
290 /*
291 * max channel will be the physical channels plus 1 virtual channel
292 * all containers are on the virtual channel 0
293 * physical channels are address by their actual physical number+1
294 */
295 host_ptr->max_channel = aac_drivers[index].channels+1;
296 } else {
297 host_ptr->max_channel = 1;
298 }
299 dprintk((KERN_DEBUG "Device has %d logical channels\n", host_ptr->max_channel));
300 aac_get_containers(aac);
301 aac_devices[aac_count-1] = aac;
303 /*
304 * dmb - we may need to move the setting of these parms somewhere else once
305 * we get a fib that can report the actual numbers
306 */
307 host_ptr->max_id = AAC_MAX_TARGET;
308 host_ptr->max_lun = AAC_MAX_LUN;
309 }
310 }
312 #if 0
313 if( aac_count ){
314 if((aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops))<0)
315 printk(KERN_WARNING "aacraid: unable to register \"aac\" device.\n");
316 }
317 #endif
318 spin_lock_irq(&io_request_lock);
320 template->present = aac_count; /* # of cards of this type found */
321 return aac_count;
322 }
324 /**
325 * aac_release - release SCSI host resources
326 * @host_ptr: SCSI host to clean up
327 *
328 * Release all resources previously acquired to support a specific Host
329 * Adapter and unregister the AAC Host Adapter.
330 *
331 * BUGS: Does not wait for the thread it kills to die.
332 */
334 static int aac_release(struct Scsi_Host *host_ptr)
335 {
336 struct aac_dev *dev;
337 dprintk((KERN_DEBUG "aac_release.\n"));
338 dev = (struct aac_dev *)host_ptr->hostdata;
339 #if 0
340 /*
341 * kill any threads we started
342 */
343 kill_proc(dev->thread_pid, SIGKILL, 0);
344 wait_for_completion(&dev->aif_completion);
345 #endif
346 /*
347 * Call the comm layer to detach from this adapter
348 */
349 aac_detach(dev);
350 /* Check free orderings... */
351 /* remove interrupt binding */
352 free_irq(host_ptr->irq, dev);
353 iounmap((void * )dev->regs.sa);
354 /* unregister adapter */
355 scsi_unregister(host_ptr);
356 /*
357 * FIXME: This assumes no hot plugging is going on...
358 */
359 if( aac_cfg_major >= 0 )
360 {
361 #if 0
362 unregister_chrdev(aac_cfg_major, "aac");
363 #endif
364 aac_cfg_major = -1;
365 }
366 return 0;
367 }
369 /**
370 * aac_queuecommand - queue a SCSI command
371 * @scsi_cmnd_ptr: SCSI command to queue
372 * @CompletionRoutine: Function to call on command completion
373 *
374 * Queues a command for execution by the associated Host Adapter.
375 */
377 static int aac_queuecommand(Scsi_Cmnd *scsi_cmnd_ptr, void (*complete)(Scsi_Cmnd *))
378 {
379 int ret;
381 scsi_cmnd_ptr->scsi_done = complete;
382 /*
383 * aac_scsi_cmd() handles command processing, setting the
384 * result code and calling completion routine.
385 */
386 if((ret = aac_scsi_cmd(scsi_cmnd_ptr)) != 0)
387 dprintk((KERN_DEBUG "aac_scsi_cmd failed.\n"));
388 return ret;
389 }
391 /**
392 * aac_driverinfo - Returns the host adapter name
393 * @host_ptr: Scsi host to report on
394 *
395 * Returns a static string describing the device in question
396 */
398 const char *aac_driverinfo(struct Scsi_Host *host_ptr)
399 {
400 struct aac_dev *dev = (struct aac_dev *)host_ptr->hostdata;
401 return aac_drivers[dev->cardtype].name;
402 }
404 /**
405 * aac_get_driver_ident
406 * @devtype: index into lookup table
407 *
408 * Returns a pointer to the entry in the driver lookup table.
409 */
410 struct aac_driver_ident* aac_get_driver_ident(int devtype)
411 {
412 return &aac_drivers[devtype];
413 }
415 /**
416 * aac_biosparm - return BIOS parameters for disk
417 * @disk: SCSI disk object to process
418 * @device: kdev_t of the disk in question
419 * @geom: geometry block to fill in
420 *
421 * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
422 * The default disk geometry is 64 heads, 32 sectors, and the appropriate
423 * number of cylinders so as not to exceed drive capacity. In order for
424 * disks equal to or larger than 1 GB to be addressable by the BIOS
425 * without exceeding the BIOS limitation of 1024 cylinders, Extended
426 * Translation should be enabled. With Extended Translation enabled,
427 * drives between 1 GB inclusive and 2 GB exclusive are given a disk
428 * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
429 * are given a disk geometry of 255 heads and 63 sectors. However, if
430 * the BIOS detects that the Extended Translation setting does not match
431 * the geometry in the partition table, then the translation inferred
432 * from the partition table will be used by the BIOS, and a warning may
433 * be displayed.
434 */
436 static int aac_biosparm(Scsi_Disk *disk, kdev_t dev, int *geom)
437 {
438 struct diskparm *param = (struct diskparm *)geom;
439 #if 0
440 struct buffer_head * buf;
441 #endif
443 dprintk((KERN_DEBUG "aac_biosparm.\n"));
445 /*
446 * Assuming extended translation is enabled - #REVISIT#
447 */
448 if( disk->capacity >= 2 * 1024 * 1024 ) /* 1 GB in 512 byte sectors */
449 {
450 if( disk->capacity >= 4 * 1024 * 1024 ) /* 2 GB in 512 byte sectors */
451 {
452 param->heads = 255;
453 param->sectors = 63;
454 }
455 else
456 {
457 param->heads = 128;
458 param->sectors = 32;
459 }
460 }
461 else
462 {
463 param->heads = 64;
464 param->sectors = 32;
465 }
467 param->cylinders = disk->capacity/(param->heads * param->sectors);
469 #if 0
470 /*
471 * Read the first 1024 bytes from the disk device
472 */
474 buf = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, block_size(dev));
475 if(buf == NULL)
476 return 0;
477 /*
478 * If the boot sector partition table is valid, search for a partition
479 * table entry whose end_head matches one of the standard geometry
480 * translations ( 64/32, 128/32, 255/63 ).
481 */
483 if(*(unsigned short *)(buf->b_data + 0x1fe) == cpu_to_le16(0xaa55))
484 {
485 struct partition *first = (struct partition * )(buf->b_data + 0x1be);
486 struct partition *entry = first;
487 int saved_cylinders = param->cylinders;
488 int num;
489 unsigned char end_head, end_sec;
491 for(num = 0; num < 4; num++)
492 {
493 end_head = entry->end_head;
494 end_sec = entry->end_sector & 0x3f;
496 if(end_head == 63)
497 {
498 param->heads = 64;
499 param->sectors = 32;
500 break;
501 }
502 else if(end_head == 127)
503 {
504 param->heads = 128;
505 param->sectors = 32;
506 break;
507 }
508 else if(end_head == 254)
509 {
510 param->heads = 255;
511 param->sectors = 63;
512 break;
513 }
514 entry++;
515 }
517 if(num == 4)
518 {
519 end_head = first->end_head;
520 end_sec = first->end_sector & 0x3f;
521 }
523 param->cylinders = disk->capacity / (param->heads * param->sectors);
525 if(num < 4 && end_sec == param->sectors)
526 {
527 if(param->cylinders != saved_cylinders)
528 dprintk((KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.\n",
529 param->heads, param->sectors, num));
530 }
531 else if(end_head > 0 || end_sec > 0)
532 {
533 dprintk((KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.\n",
534 end_head + 1, end_sec, num));
535 dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.\n",
536 param->heads, param->sectors));
537 }
538 }
539 brelse(buf);
540 #endif
541 return 0;
542 }
544 /**
545 * aac_queuedepth - compute queue depths
546 * @host: SCSI host in question
547 * @dev: SCSI device we are considering
548 *
549 * Selects queue depths for each target device based on the host adapter's
550 * total capacity and the queue depth supported by the target device.
551 * A queue depth of one automatically disables tagged queueing.
552 */
554 static void aac_queuedepth(struct Scsi_Host * host, Scsi_Device * dev )
555 {
556 Scsi_Device * dptr;
558 dprintk((KERN_DEBUG "aac_queuedepth.\n"));
559 dprintk((KERN_DEBUG "Device # Q Depth Online\n"));
560 dprintk((KERN_DEBUG "---------------------------\n"));
561 for(dptr = dev; dptr != NULL; dptr = dptr->next)
562 {
563 if(dptr->host == host)
564 {
565 dptr->queue_depth = 10;
566 dprintk((KERN_DEBUG " %2d %d %d\n",
567 dptr->id, dptr->queue_depth, dptr->online));
568 }
569 }
570 }
573 /**
574 * aac_eh_abort - Abort command if possible.
575 * @cmd: SCSI command block to abort
576 *
577 * Called when the midlayer wishes to abort a command. We don't support
578 * this facility, and our firmware looks after life for us. We just
579 * report this as failing
580 */
582 static int aac_eh_abort(Scsi_Cmnd *cmd)
583 {
584 return FAILED;
585 }
587 /**
588 * aac_eh_device_reset - Reset command handling
589 * @cmd: SCSI command block causing the reset
590 *
591 * Issue a reset of a SCSI device. We are ourselves not truely a SCSI
592 * controller and our firmware will do the work for us anyway. Thus this
593 * is a no-op. We just return FAILED.
594 */
596 static int aac_eh_device_reset(Scsi_Cmnd *cmd)
597 {
598 return FAILED;
599 }
601 /**
602 * aac_eh_bus_reset - Reset command handling
603 * @scsi_cmd: SCSI command block causing the reset
604 *
605 * Issue a reset of a SCSI bus. We are ourselves not truely a SCSI
606 * controller and our firmware will do the work for us anyway. Thus this
607 * is a no-op. We just return FAILED.
608 */
610 static int aac_eh_bus_reset(Scsi_Cmnd* cmd)
611 {
612 return FAILED;
613 }
615 /**
616 * aac_eh_hba_reset - Reset command handling
617 * @scsi_cmd: SCSI command block causing the reset
618 *
619 * Issue a reset of a SCSI host. If things get this bad then arguably we should
620 * go take a look at what the host adapter is doing and see if something really
621 * broke (as can occur at least on my Dell QC card if a drive keeps failing spinup)
622 */
624 static int aac_eh_reset(Scsi_Cmnd* cmd)
625 {
626 printk(KERN_ERR "aacraid: Host adapter reset request. SCSI hang ?\n");
627 return FAILED;
628 }
630 /**
631 * aac_ioctl - Handle SCSI ioctls
632 * @scsi_dev_ptr: scsi device to operate upon
633 * @cmd: ioctl command to use issue
634 * @arg: ioctl data pointer
635 *
636 * Issue an ioctl on an aacraid device. Returns a standard unix error code or
637 * zero for success
638 */
640 static int aac_ioctl(Scsi_Device * scsi_dev_ptr, int cmd, void * arg)
641 {
642 struct aac_dev *dev;
643 dprintk((KERN_DEBUG "aac_ioctl.\n"));
644 dev = (struct aac_dev *)scsi_dev_ptr->host->hostdata;
645 return aac_do_ioctl(dev, cmd, arg);
646 }
648 /**
649 * aac_cfg_open - open a configuration file
650 * @inode: inode being opened
651 * @file: file handle attached
652 *
653 * Called when the configuration device is opened. Does the needed
654 * set up on the handle and then returns
655 *
656 * Bugs: This needs extending to check a given adapter is present
657 * so we can support hot plugging, and to ref count adapters.
658 */
660 static int aac_cfg_open(struct inode * inode, struct file * file )
661 {
662 unsigned minor_number = MINOR(inode->i_rdev);
663 if(minor_number >= aac_count)
664 return -ENODEV;
665 return 0;
666 }
668 /**
669 * aac_cfg_release - close down an AAC config device
670 * @inode: inode of configuration file
671 * @file: file handle of configuration file
672 *
673 * Called when the last close of the configuration file handle
674 * is performed.
675 */
677 static int aac_cfg_release(struct inode * inode, struct file * file )
678 {
679 return 0;
680 }
682 /**
683 * aac_cfg_ioctl - AAC configuration request
684 * @inode: inode of device
685 * @file: file handle
686 * @cmd: ioctl command code
687 * @arg: argument
688 *
689 * Handles a configuration ioctl. Currently this involves wrapping it
690 * up and feeding it into the nasty windowsalike glue layer.
691 *
692 * Bugs: Needs locking against parallel ioctls lower down
693 * Bugs: Needs to handle hot plugging
694 */
696 static int aac_cfg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg )
697 {
698 struct aac_dev *dev = aac_devices[MINOR(inode->i_rdev)];
699 return aac_do_ioctl(dev, cmd, (void *)arg);
700 }
702 /*
703 * To use the low level SCSI driver support using the linux kernel loadable
704 * module interface we should initialize the global variable driver_interface
705 * (datatype Scsi_Host_Template) and then include the file scsi_module.c.
706 */
708 static Scsi_Host_Template driver_template = {
709 #if 0
710 module: THIS_MODULE,
711 #endif
712 name: "AAC",
713 #if 0
714 proc_info: aac_procinfo,
715 #endif
716 detect: aac_detect,
717 release: aac_release,
718 info: aac_driverinfo,
719 ioctl: aac_ioctl,
720 queuecommand: aac_queuecommand,
721 bios_param: aac_biosparm,
722 can_queue: AAC_NUM_IO_FIB,
723 this_id: 16,
724 sg_tablesize: 16,
725 max_sectors: 128,
726 cmd_per_lun: AAC_NUM_IO_FIB,
727 eh_abort_handler: aac_eh_abort,
728 eh_device_reset_handler:aac_eh_device_reset,
729 eh_bus_reset_handler: aac_eh_bus_reset,
730 eh_host_reset_handler: aac_eh_reset,
731 use_new_eh_code: 1,
733 use_clustering: ENABLE_CLUSTERING,
734 };
736 #include "../scsi_module.c.inc"
738 #ifdef CONFIG_PROC_FS
739 /**
740 * aac_procinfo - Implement /proc/scsi/<drivername>/<n>
741 * @proc_buffer: memory buffer for I/O
742 * @start_ptr: pointer to first valid data
743 * @offset: offset into file
744 * @bytes_available: space left
745 * @host_no: scsi host ident
746 * @write: direction of I/O
747 *
748 * Used to export driver statistics and other infos to the world outside
749 * the kernel using the proc file system. Also provides an interface to
750 * feed the driver with information.
751 *
752 * For reads
753 * - if offset > 0 return 0
754 * - if offset == 0 write data to proc_buffer and set the start_ptr to
755 * beginning of proc_buffer, return the number of characters written.
756 * For writes
757 * - writes currently not supported, return 0
758 *
759 * Bugs: Only offset zero is handled
760 */
762 static int aac_procinfo(char *proc_buffer, char **start_ptr,off_t offset,
763 int bytes_available, int host_no, int write)
764 {
765 if(write || offset > 0)
766 return 0;
767 *start_ptr = proc_buffer;
768 return sprintf(proc_buffer,
769 "Adaptec Raid Controller %s %s, scsi hba number %d\n",
770 AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE,
771 host_no);
772 }
773 #endif
775 EXPORT_NO_SYMBOLS;