ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / scsi / inia100.c
1 /**************************************************************************
2  * Initio A100 device driver for Linux.
3  *
4  * Copyright (c) 1994-1998 Initio Corporation
5  * All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * --------------------------------------------------------------------------
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions, and the following disclaimer,
28  *    without modification, immediately at the beginning of the file.
29  * 2. Redistributions in binary form must reproduce the above copyright
30  *    notice, this list of conditions and the following disclaimer in the
31  *    documentation and/or other materials provided with the distribution.
32  * 3. The name of the author may not be used to endorse or promote products
33  *    derived from this software without specific prior written permission.
34  *
35  * Where this Software is combined with software released under the terms of 
36  * the GNU General Public License ("GPL") and the terms of the GPL would require the 
37  * combined work to also be released under the terms of the GPL, the terms
38  * and conditions of this License will apply in addition to those of the
39  * GPL with the exception of any terms or conditions of this License that
40  * conflict with, or are expressly prohibited by, the GPL.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
46  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  *
54  **************************************************************************
55  * 
56  * module: inia100.c
57  * DESCRIPTION:
58  *      This is the Linux low-level SCSI driver for Initio INIA100 SCSI host
59  *      adapters
60  * 09/24/98 hl - v1.02 initial production release.
61  * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up.
62  * 06/25/02 Doug Ledford <dledford@redhat.com> - v1.02d
63  *          - Remove limit on number of controllers
64  *          - Port to DMA mapping API
65  *          - Clean up interrupt handler registration
66  *          - Fix memory leaks
67  *          - Fix allocation of scsi host structs and private data
68  * 18/11/03 Christoph Hellwig <hch@lst.de>
69  *          - Port to new probing API
70  *          - Fix some more leaks in init failure cases
71  * TODO:
72  *          - use list.h macros for SCB queue
73  *        ( - merge with i60uscsi.c )
74  **************************************************************************/
75
76 #include <linux/module.h>
77 #include <linux/errno.h>
78 #include <linux/delay.h>
79 #include <linux/interrupt.h>
80 #include <linux/pci.h>
81 #include <linux/init.h>
82 #include <linux/blkdev.h>
83 #include <linux/spinlock.h>
84 #include <linux/kernel.h>
85 #include <linux/string.h>
86 #include <linux/ioport.h>
87 #include <linux/slab.h>
88 #include <asm/io.h>
89 #include <asm/irq.h>
90
91 #include <scsi/scsi.h>
92 #include <scsi/scsi_cmnd.h>
93 #include <scsi/scsi_device.h>
94 #include <scsi/scsi_host.h>
95
96 #include "inia100.h"
97
98 #define ORC_RDWORD(x,y)         (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
99
100 char *inia100_Copyright = "Copyright (C) 1998-99";
101 char *inia100_InitioName = "by Initio Corporation";
102 char *inia100_ProductName = "INI-A100U2W";
103 char *inia100_Version = "v1.02d";
104
105 /* ---- EXTERNAL FUNCTIONS ---- */
106 extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
107 extern int init_inia100Adapter_table(int);
108 extern ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
109 extern void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
110 extern void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp);
111 extern void orc_release_dma(ORC_HCS * hcsp, struct scsi_cmnd * cmnd);
112 extern void orc_interrupt(ORC_HCS * hcsp);
113 extern int orc_device_reset(ORC_HCS * pHCB, struct scsi_cmnd *SCpnt, unsigned int target);
114 extern int orc_reset_scsi_bus(ORC_HCS * pHCB);
115 extern int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb);
116 extern int orc_abort_srb(ORC_HCS * hcsp, struct scsi_cmnd *SCpnt);
117 extern int init_orchid(ORC_HCS * hcsp);
118
119 /*****************************************************************************
120  Function name  : inia100AppendSRBToQueue
121  Description    : This function will push current request into save list
122  Input          : pSRB  -       Pointer to SCSI request block.
123                   pHCB  -       Pointer to host adapter structure
124  Output         : None.
125  Return         : None.
126 *****************************************************************************/
127 static void inia100AppendSRBToQueue(ORC_HCS * pHCB, struct scsi_cmnd * pSRB)
128 {
129         ULONG flags;
130
131         spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
132
133         pSRB->SCp.ptr = NULL;   /* Pointer to next */
134         if (pHCB->pSRB_head == NULL)
135                 pHCB->pSRB_head = pSRB;
136         else
137                 pHCB->pSRB_tail->SCp.ptr = (char *)pSRB;        /* Pointer to next */
138         pHCB->pSRB_tail = pSRB;
139         spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
140         return;
141 }
142
143 /*****************************************************************************
144  Function name  : inia100PopSRBFromQueue
145  Description    : This function will pop current request from save list
146  Input          : pHCB  -       Pointer to host adapter structure
147  Output         : None.
148  Return         : pSRB  -       Pointer to SCSI request block.
149 *****************************************************************************/
150 static struct scsi_cmnd *inia100PopSRBFromQueue(ORC_HCS * pHCB)
151 {
152         struct scsi_cmnd *pSRB;
153         ULONG flags;
154         spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
155         if ((pSRB = (struct scsi_cmnd *) pHCB->pSRB_head) != NULL) {
156                 pHCB->pSRB_head = (struct scsi_cmnd *) pHCB->pSRB_head->SCp.ptr;
157                 pSRB->SCp.ptr = NULL;
158         }
159         spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
160         return (pSRB);
161 }
162
163 /*****************************************************************************
164  Function name  : inia100BuildSCB
165  Description    : 
166  Input          : pHCB  -       Pointer to host adapter structure
167  Output         : None.
168  Return         : pSRB  -       Pointer to SCSI request block.
169 *****************************************************************************/
170 static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * SCpnt)
171 {                               /* Create corresponding SCB     */
172         struct scatterlist *pSrbSG;
173         ORC_SG *pSG;            /* Pointer to SG list           */
174         int i, count_sg;
175         U32 TotalLen;
176         ESCB *pEScb;
177
178         pEScb = pSCB->SCB_EScb;
179         pEScb->SCB_Srb = SCpnt;
180         pSG = NULL;
181
182         pSCB->SCB_Opcode = ORC_EXECSCSI;
183         pSCB->SCB_Flags = SCF_NO_DCHK;  /* Clear done bit               */
184         pSCB->SCB_Target = SCpnt->device->id;
185         pSCB->SCB_Lun = SCpnt->device->lun;
186         pSCB->SCB_Reserved0 = 0;
187         pSCB->SCB_Reserved1 = 0;
188         pSCB->SCB_SGLen = 0;
189
190         if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) {
191                 pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];
192                 if (SCpnt->use_sg) {
193                         TotalLen = 0;
194                         pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
195                         count_sg = pci_map_sg(pHCB->pdev, pSrbSG, SCpnt->use_sg,
196                                         SCpnt->sc_data_direction);
197                         pSCB->SCB_SGLen = (U32) (count_sg * 8);
198                         for (i = 0; i < count_sg; i++, pSG++, pSrbSG++) {
199                                 pSG->SG_Ptr = (U32) sg_dma_address(pSrbSG);
200                                 pSG->SG_Len = (U32) sg_dma_len(pSrbSG);
201                                 TotalLen += (U32) sg_dma_len(pSrbSG);
202                         }
203                 } else if (SCpnt->request_bufflen != 0) {/* Non SG */
204                         pSCB->SCB_SGLen = 0x8;
205                         pSG->SG_Ptr = (U32) pci_map_single(pHCB->pdev,
206                                 SCpnt->request_buffer, SCpnt->request_bufflen,
207                                 SCpnt->sc_data_direction);
208                         SCpnt->host_scribble = (void *)pSG->SG_Ptr;
209                         pSG->SG_Len = (U32) SCpnt->request_bufflen;
210                 } else {
211                         pSCB->SCB_SGLen = 0;
212                         pSG->SG_Ptr = 0;
213                         pSG->SG_Len = 0;
214                 }
215         }
216         pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr;
217         pSCB->SCB_HaStat = 0;
218         pSCB->SCB_TaStat = 0;
219         pSCB->SCB_Link = 0xFF;
220         pSCB->SCB_SenseLen = SENSE_SIZE;
221         pSCB->SCB_CDBLen = SCpnt->cmd_len;
222         if (pSCB->SCB_CDBLen >= IMAX_CDB) {
223                 printk("max cdb length= %x\b", SCpnt->cmd_len);
224                 pSCB->SCB_CDBLen = IMAX_CDB;
225         }
226         pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
227         if (SCpnt->device->tagged_supported) {  /* Tag Support                  */
228                 pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;    /* Do simple tag only   */
229         } else {
230                 pSCB->SCB_TagMsg = 0;   /* No tag support               */
231         }
232         memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen);
233         return;
234 }
235
236 /*****************************************************************************
237  Function name  : inia100_queue
238  Description    : Queue a command and setup interrupts for a free bus.
239  Input          : pHCB  -       Pointer to host adapter structure
240  Output         : None.
241  Return         : pSRB  -       Pointer to SCSI request block.
242 *****************************************************************************/
243 static int inia100_queue(struct scsi_cmnd * SCpnt, void (*done) (struct scsi_cmnd *))
244 {
245         register ORC_SCB *pSCB;
246         ORC_HCS *pHCB;          /* Point to Host adapter control block */
247
248         pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
249         SCpnt->scsi_done = done;
250         /* Get free SCSI control block  */
251         if ((pSCB = orc_alloc_scb(pHCB)) == NULL) {
252                 inia100AppendSRBToQueue(pHCB, SCpnt);   /* Buffer this request  */
253                 /* printk("inia100_entry: can't allocate SCB\n"); */
254                 return (0);
255         }
256         inia100BuildSCB(pHCB, pSCB, SCpnt);
257         orc_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
258
259         return (0);
260 }
261
262 /*****************************************************************************
263  Function name  : inia100_abort
264  Description    : Abort a queued command.
265                          (commands that are on the bus can't be aborted easily)
266  Input          : pHCB  -       Pointer to host adapter structure
267  Output         : None.
268  Return         : pSRB  -       Pointer to SCSI request block.
269 *****************************************************************************/
270 static int inia100_abort(struct scsi_cmnd * SCpnt)
271 {
272         ORC_HCS *hcsp;
273
274         hcsp = (ORC_HCS *) SCpnt->device->host->hostdata;
275         return orc_abort_srb(hcsp, SCpnt);
276 }
277
278 /*****************************************************************************
279  Function name  : inia100_reset
280  Description    : Reset registers, reset a hanging bus and
281                   kill active and disconnected commands for target w/o soft reset
282  Input          : pHCB  -       Pointer to host adapter structure
283  Output         : None.
284  Return         : pSRB  -       Pointer to SCSI request block.
285 *****************************************************************************/
286 static int inia100_bus_reset(struct scsi_cmnd * SCpnt)
287 {                               /* I need Host Control Block Information */
288         ORC_HCS *pHCB;
289         pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
290         return orc_reset_scsi_bus(pHCB);
291 }
292
293 /*****************************************************************************
294  Function name  : inia100_device_reset
295  Description    : Reset the device
296  Input          : pHCB  -       Pointer to host adapter structure
297  Output         : None.
298  Return         : pSRB  -       Pointer to SCSI request block.
299 *****************************************************************************/
300 static int inia100_device_reset(struct scsi_cmnd * SCpnt)
301 {                               /* I need Host Control Block Information */
302         ORC_HCS *pHCB;
303         pHCB = (ORC_HCS *) SCpnt->device->host->hostdata;
304         return orc_device_reset(pHCB, SCpnt, SCpnt->device->id);
305
306 }
307
308 /*****************************************************************************
309  Function name  : inia100SCBPost
310  Description    : This is callback routine be called when orc finish one
311                         SCSI command.
312  Input          : pHCB  -       Pointer to host adapter control block.
313                   pSCB  -       Pointer to SCSI control block.
314  Output         : None.
315  Return         : None.
316 *****************************************************************************/
317 void inia100SCBPost(BYTE * pHcb, BYTE * pScb)
318 {
319         struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */
320         ORC_HCS *pHCB;
321         ORC_SCB *pSCB;
322         ESCB *pEScb;
323
324         pHCB = (ORC_HCS *) pHcb;
325         pSCB = (ORC_SCB *) pScb;
326         pEScb = pSCB->SCB_EScb;
327         if ((pSRB = (struct scsi_cmnd *) pEScb->SCB_Srb) == 0) {
328                 printk("inia100SCBPost: SRB pointer is empty\n");
329                 orc_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
330                 return;
331         }
332         pEScb->SCB_Srb = NULL;
333
334         switch (pSCB->SCB_HaStat) {
335         case 0x0:
336         case 0xa:               /* Linked command complete without error and linked normally */
337         case 0xb:               /* Linked command complete without error interrupt generated */
338                 pSCB->SCB_HaStat = 0;
339                 break;
340
341         case 0x11:              /* Selection time out-The initiator selection or target
342                                    reselection was not complete within the SCSI Time out period */
343                 pSCB->SCB_HaStat = DID_TIME_OUT;
344                 break;
345
346         case 0x14:              /* Target bus phase sequence failure-An invalid bus phase or bus
347                                    phase sequence was requested by the target. The host adapter
348                                    will generate a SCSI Reset Condition, notifying the host with
349                                    a SCRD interrupt */
350                 pSCB->SCB_HaStat = DID_RESET;
351                 break;
352
353         case 0x1a:              /* SCB Aborted. 07/21/98 */
354                 pSCB->SCB_HaStat = DID_ABORT;
355                 break;
356
357         case 0x12:              /* Data overrun/underrun-The target attempted to transfer more data
358                                    than was allocated by the Data Length field or the sum of the
359                                    Scatter / Gather Data Length fields. */
360         case 0x13:              /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
361         case 0x16:              /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */
362
363         default:
364                 printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
365                 pSCB->SCB_HaStat = DID_ERROR;   /* Couldn't find any better */
366                 break;
367         }
368
369         if (pSCB->SCB_TaStat == 2) {    /* Check condition              */
370                 memcpy((unsigned char *) &pSRB->sense_buffer[0],
371                    (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE);
372         }
373         pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
374         orc_release_dma(pHCB, pSRB);  /* release DMA before we call scsi_done */
375         pSRB->scsi_done(pSRB);  /* Notify system DONE           */
376
377         /* Find the next pending SRB    */
378         if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) {    /* Assume resend will success   */
379                 inia100BuildSCB(pHCB, pSCB, pSRB);      /* Create corresponding SCB     */
380                 orc_exec_scb(pHCB, pSCB);       /* Start execute SCB            */
381         } else {
382                 orc_release_scb(pHCB, pSCB);    /* Release SCB for current channel */
383         }
384         return;
385 }
386
387 /*
388  * Interrupt handler (main routine of the driver)
389  */
390 static irqreturn_t inia100_intr(int irqno, void *devid, struct pt_regs *regs)
391 {
392         struct Scsi_Host *host = (struct Scsi_Host *)devid;
393         ORC_HCS *pHcb = (ORC_HCS *)host->hostdata;
394         unsigned long flags;
395
396         spin_lock_irqsave(host->host_lock, flags);
397         orc_interrupt(pHcb);
398         spin_unlock_irqrestore(host->host_lock, flags);
399
400         return IRQ_HANDLED;
401 }
402
403 static struct scsi_host_template inia100_template = {
404         .proc_name              = "inia100",
405         .name                   = inia100_REVID,
406         .queuecommand           = inia100_queue,
407         .eh_abort_handler       = inia100_abort,
408         .eh_bus_reset_handler   = inia100_bus_reset,
409         .eh_device_reset_handler = inia100_device_reset,
410         .can_queue              = 1,
411         .this_id                = 1,
412         .sg_tablesize           = SG_ALL,
413         .cmd_per_lun            = 1,
414         .use_clustering         = ENABLE_CLUSTERING,
415 };
416
417 static int __devinit inia100_probe_one(struct pci_dev *pdev,
418                 const struct pci_device_id *id)
419 {
420         struct Scsi_Host *shost;
421         ORC_HCS *pHCB;
422         unsigned long port, bios;
423         int error = -ENODEV;
424         u32 sz;
425         unsigned long dBiosAdr;
426         char *pbBiosAdr;
427
428         if (pci_enable_device(pdev))
429                 goto out;
430         if (pci_set_dma_mask(pdev, 0xffffffffULL)) {
431                 printk(KERN_WARNING "Unable to set 32bit DMA "
432                                     "on inia100 adapter, ignoring.\n");
433                 goto out_disable_device;
434         }
435
436         pci_set_master(pdev);
437
438         port = pci_resource_start(pdev, 0);
439         if (!request_region(port, 256, "inia100")) {
440                 printk(KERN_WARNING "inia100: io port 0x%lx, is busy.\n", port);
441                 goto out_disable_device;
442         }
443
444         /* <02> read from base address + 0x50 offset to get the bios balue. */
445         bios = ORC_RDWORD(port, 0x50);
446
447
448         shost = scsi_host_alloc(&inia100_template, sizeof(ORC_HCS));
449         if (!shost)
450                 goto out_release_region;
451
452         pHCB = (ORC_HCS *)shost->hostdata;
453         pHCB->pdev = pdev;
454         pHCB->HCS_Base = port;
455         pHCB->HCS_BIOS = bios;
456         pHCB->pSRB_head = NULL; /* Initial SRB save queue       */
457         pHCB->pSRB_tail = NULL; /* Initial SRB save queue       */
458         pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */
459         pHCB->BitAllocFlagLock = SPIN_LOCK_UNLOCKED;
460
461         /* Get total memory needed for SCB */
462         sz = ORC_MAXQUEUE * sizeof(ORC_SCB);
463         pHCB->HCS_virScbArray = pci_alloc_consistent(pdev, sz,
464                         &pHCB->HCS_physScbArray);
465         if (!pHCB->HCS_virScbArray) {
466                 printk("inia100: SCB memory allocation error\n");
467                 goto out_host_put;
468         }
469         memset(pHCB->HCS_virScbArray, 0, sz);
470
471         /* Get total memory needed for ESCB */
472         sz = ORC_MAXQUEUE * sizeof(ESCB);
473         pHCB->HCS_virEscbArray = pci_alloc_consistent(pdev, sz,
474                         &pHCB->HCS_physEscbArray);
475         if (!pHCB->HCS_virEscbArray) {
476                 printk("inia100: ESCB memory allocation error\n");
477                 goto out_free_scb_array;
478         }
479         memset(pHCB->HCS_virEscbArray, 0, sz);
480
481         dBiosAdr = pHCB->HCS_BIOS;
482         dBiosAdr = (dBiosAdr << 4);
483         pbBiosAdr = phys_to_virt(dBiosAdr);
484         if (init_orchid(pHCB)) {        /* Initialize orchid chip */
485                 printk("inia100: initial orchid fail!!\n");
486                 goto out_free_escb_array;
487         }
488
489         shost->io_port = pHCB->HCS_Base;
490         shost->n_io_port = 0xff;
491         shost->can_queue = ORC_MAXQUEUE;
492         shost->unique_id = shost->io_port;
493         shost->max_id = pHCB->HCS_MaxTar;
494         shost->max_lun = 16;
495         shost->irq = pHCB->HCS_Intr = pdev->irq;
496         shost->this_id = pHCB->HCS_SCSI_ID;     /* Assign HCS index */
497         shost->sg_tablesize = TOTAL_SG_ENTRY;
498
499         /* Initial orc chip           */
500         error = request_irq(pdev->irq, inia100_intr, SA_SHIRQ,
501                         "inia100", shost);
502         if (error < 0) {
503                 printk(KERN_WARNING "inia100: unable to get irq %d\n",
504                                 pdev->irq);
505                 goto out_free_escb_array;
506         }
507
508         pci_set_drvdata(pdev, shost);
509
510         error = scsi_add_host(shost, &pdev->dev);
511         if (error)
512                 goto out_free_irq;
513
514         scsi_scan_host(shost);
515         return 0;
516
517  out_free_irq:
518         free_irq(shost->irq, shost);
519  out_free_escb_array:
520         pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB),
521                         pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray);
522  out_free_scb_array:
523         pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB),
524                         pHCB->HCS_virScbArray, pHCB->HCS_physScbArray);
525  out_host_put:
526         scsi_host_put(shost);
527  out_release_region:
528         release_region(port, 256);
529  out_disable_device:
530         pci_disable_device(pdev);
531  out:
532         return error;
533 }
534
535 static void __devexit inia100_remove_one(struct pci_dev *pdev)
536 {
537         struct Scsi_Host *shost = pci_get_drvdata(pdev);
538         ORC_HCS *pHCB = (ORC_HCS *)shost->hostdata;
539
540         scsi_remove_host(shost);
541
542         free_irq(shost->irq, shost);
543         pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB),
544                         pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray);
545         pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB),
546                         pHCB->HCS_virScbArray, pHCB->HCS_physScbArray);
547         release_region(shost->io_port, 256);
548
549         scsi_host_put(shost);
550
551
552 static struct pci_device_id inia100_pci_tbl[] = {
553         {ORC_VENDOR_ID, ORC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
554         {0,}
555 };
556 MODULE_DEVICE_TABLE(pci, inia100_pci_tbl);
557
558 static struct pci_driver inia100_pci_driver = {
559         .name           = "inia100",
560         .id_table       = inia100_pci_tbl,
561         .probe          = inia100_probe_one,
562         .remove         = __devexit_p(inia100_remove_one),
563 };
564
565 static int __init inia100_init(void)
566 {
567         return pci_module_init(&inia100_pci_driver);
568 }
569
570 static void __exit inia100_exit(void)
571 {
572         pci_unregister_driver(&inia100_pci_driver);
573 }
574
575 MODULE_DESCRIPTION("Initio A100U2W SCSI driver");
576 MODULE_AUTHOR("Initio Corporation");
577 MODULE_LICENSE("Dual BSD/GPL");
578
579 module_init(inia100_init);
580 module_exit(inia100_exit);