1 /**************************************************************************
2 * Initio A100 device driver for Linux.
4 * Copyright (c) 1994-1998 Initio Corporation
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)
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.
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.
21 * --------------------------------------------------------------------------
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
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.
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.
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
54 **************************************************************************
58 * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host
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
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
72 * - use list.h macros for SCB queue
73 * ( - merge with i60uscsi.c )
74 **************************************************************************/
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>
91 #include <scsi/scsi.h>
92 #include <scsi/scsi_cmnd.h>
93 #include <scsi/scsi_device.h>
94 #include <scsi/scsi_host.h>
98 #define ORC_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
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";
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
);
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
126 *****************************************************************************/
127 static void inia100AppendSRBToQueue(ORC_HCS
* pHCB
, struct scsi_cmnd
* pSRB
)
131 spin_lock_irqsave(&(pHCB
->pSRB_lock
), flags
);
133 pSRB
->SCp
.ptr
= NULL
; /* Pointer to next */
134 if (pHCB
->pSRB_head
== NULL
)
135 pHCB
->pSRB_head
= pSRB
;
137 pHCB
->pSRB_tail
->SCp
.ptr
= (char *)pSRB
; /* Pointer to next */
138 pHCB
->pSRB_tail
= pSRB
;
139 spin_unlock_irqrestore(&(pHCB
->pSRB_lock
), flags
);
143 /*****************************************************************************
144 Function name : inia100PopSRBFromQueue
145 Description : This function will pop current request from save list
146 Input : pHCB - Pointer to host adapter structure
148 Return : pSRB - Pointer to SCSI request block.
149 *****************************************************************************/
150 static struct scsi_cmnd
*inia100PopSRBFromQueue(ORC_HCS
* pHCB
)
152 struct scsi_cmnd
*pSRB
;
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
;
159 spin_unlock_irqrestore(&(pHCB
->pSRB_lock
), flags
);
163 /*****************************************************************************
164 Function name : inia100BuildSCB
166 Input : pHCB - Pointer to host adapter structure
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 */
178 pEScb
= pSCB
->SCB_EScb
;
179 pEScb
->SCB_Srb
= SCpnt
;
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;
190 if ((pSCB
->SCB_XferLen
= (U32
) SCpnt
->request_bufflen
)) {
191 pSG
= (ORC_SG
*) & pEScb
->ESCB_SGList
[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
);
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
;
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
;
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 */
230 pSCB
->SCB_TagMsg
= 0; /* No tag support */
232 memcpy(&pSCB
->SCB_CDB
[0], &SCpnt
->cmnd
, pSCB
->SCB_CDBLen
);
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
241 Return : pSRB - Pointer to SCSI request block.
242 *****************************************************************************/
243 static int inia100_queue(struct scsi_cmnd
* SCpnt
, void (*done
) (struct scsi_cmnd
*))
245 register ORC_SCB
*pSCB
;
246 ORC_HCS
*pHCB
; /* Point to Host adapter control block */
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"); */
256 inia100BuildSCB(pHCB
, pSCB
, SCpnt
);
257 orc_exec_scb(pHCB
, pSCB
); /* Start execute SCB */
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
268 Return : pSRB - Pointer to SCSI request block.
269 *****************************************************************************/
270 static int inia100_abort(struct scsi_cmnd
* SCpnt
)
274 hcsp
= (ORC_HCS
*) SCpnt
->device
->host
->hostdata
;
275 return orc_abort_srb(hcsp
, SCpnt
);
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
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 */
289 pHCB
= (ORC_HCS
*) SCpnt
->device
->host
->hostdata
;
290 return orc_reset_scsi_bus(pHCB
);
293 /*****************************************************************************
294 Function name : inia100_device_reset
295 Description : Reset the device
296 Input : pHCB - Pointer to host adapter structure
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 */
303 pHCB
= (ORC_HCS
*) SCpnt
->device
->host
->hostdata
;
304 return orc_device_reset(pHCB
, SCpnt
, SCpnt
->device
->id
);
308 /*****************************************************************************
309 Function name : inia100SCBPost
310 Description : This is callback routine be called when orc finish one
312 Input : pHCB - Pointer to host adapter control block.
313 pSCB - Pointer to SCSI control block.
316 *****************************************************************************/
317 void inia100SCBPost(BYTE
* pHcb
, BYTE
* pScb
)
319 struct scsi_cmnd
*pSRB
; /* Pointer to SCSI request block */
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 */
332 pEScb
->SCB_Srb
= NULL
;
334 switch (pSCB
->SCB_HaStat
) {
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;
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
;
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
350 pSCB
->SCB_HaStat
= DID_RESET
;
353 case 0x1a: /* SCB Aborted. 07/21/98 */
354 pSCB
->SCB_HaStat
= DID_ABORT
;
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. */
364 printk("inia100: %x %x\n", pSCB
->SCB_HaStat
, pSCB
->SCB_TaStat
);
365 pSCB
->SCB_HaStat
= DID_ERROR
; /* Couldn't find any better */
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
);
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 */
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 */
382 orc_release_scb(pHCB
, pSCB
); /* Release SCB for current channel */
388 * Interrupt handler (main routine of the driver)
390 static irqreturn_t
inia100_intr(int irqno
, void *devid
, struct pt_regs
*regs
)
392 struct Scsi_Host
*host
= (struct Scsi_Host
*)devid
;
393 ORC_HCS
*pHcb
= (ORC_HCS
*)host
->hostdata
;
396 spin_lock_irqsave(host
->host_lock
, flags
);
398 spin_unlock_irqrestore(host
->host_lock
, flags
);
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
,
412 .sg_tablesize
= SG_ALL
,
414 .use_clustering
= ENABLE_CLUSTERING
,
417 static int __devinit
inia100_probe_one(struct pci_dev
*pdev
,
418 const struct pci_device_id
*id
)
420 struct Scsi_Host
*shost
;
422 unsigned long port
, bios
;
425 unsigned long dBiosAdr
;
428 if (pci_enable_device(pdev
))
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
;
436 pci_set_master(pdev
);
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
;
444 /* <02> read from base address + 0x50 offset to get the bios balue. */
445 bios
= ORC_RDWORD(port
, 0x50);
448 shost
= scsi_host_alloc(&inia100_template
, sizeof(ORC_HCS
));
450 goto out_release_region
;
452 pHCB
= (ORC_HCS
*)shost
->hostdata
;
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
;
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");
469 memset(pHCB
->HCS_virScbArray
, 0, sz
);
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
;
479 memset(pHCB
->HCS_virEscbArray
, 0, sz
);
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
;
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
;
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
;
499 /* Initial orc chip */
500 error
= request_irq(pdev
->irq
, inia100_intr
, SA_SHIRQ
,
503 printk(KERN_WARNING
"inia100: unable to get irq %d\n",
505 goto out_free_escb_array
;
508 pci_set_drvdata(pdev
, shost
);
510 error
= scsi_add_host(shost
, &pdev
->dev
);
514 scsi_scan_host(shost
);
518 free_irq(shost
->irq
, shost
);
520 pci_free_consistent(pdev
, ORC_MAXQUEUE
* sizeof(ESCB
),
521 pHCB
->HCS_virEscbArray
, pHCB
->HCS_physEscbArray
);
523 pci_free_consistent(pdev
, ORC_MAXQUEUE
* sizeof(ORC_SCB
),
524 pHCB
->HCS_virScbArray
, pHCB
->HCS_physScbArray
);
526 scsi_host_put(shost
);
528 release_region(port
, 256);
530 pci_disable_device(pdev
);
535 static void __devexit
inia100_remove_one(struct pci_dev
*pdev
)
537 struct Scsi_Host
*shost
= pci_get_drvdata(pdev
);
538 ORC_HCS
*pHCB
= (ORC_HCS
*)shost
->hostdata
;
540 scsi_remove_host(shost
);
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);
549 scsi_host_put(shost
);
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},
556 MODULE_DEVICE_TABLE(pci
, inia100_pci_tbl
);
558 static struct pci_driver inia100_pci_driver
= {
560 .id_table
= inia100_pci_tbl
,
561 .probe
= inia100_probe_one
,
562 .remove
= __devexit_p(inia100_remove_one
),
565 static int __init
inia100_init(void)
567 return pci_module_init(&inia100_pci_driver
);
570 static void __exit
inia100_exit(void)
572 pci_unregister_driver(&inia100_pci_driver
);
575 MODULE_DESCRIPTION("Initio A100U2W SCSI driver");
576 MODULE_AUTHOR("Initio Corporation");
577 MODULE_LICENSE("Dual BSD/GPL");
579 module_init(inia100_init
);
580 module_exit(inia100_exit
);