Made a call which was to sleep() use tsleep() instead.
[unix-history] / sys / i386 / isa / seagate.c
CommitLineData
d7e75661
SV
1/*
2 * (Free/Net/386)BSD ST01/02, Future Domain TMC-885, TMC-950 SCSI driver for
3 * Julians SCSI-code
4 *
5 * Copyright 1994, Kent Palmkvist (kentp@isy.liu.se)
6 * Copyright 1994, Robert Knier (rknier@qgraph.com)
7 * Copyright 1992, 1994 Drew Eckhardt (drew@colorado.edu)
8 * Copyright 1994, Julian Elischer (julian@tfs.com)
9 *
10 * Others that has contributed by example code is
11 * Glen Overby (overby@cray.com)
12 * Tatu Yllnen
13 * Brian E Litzinger
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPERS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37/*
38 *
39 * kentp 940307 alpha version based on newscsi-03 version of Julians SCSI-code
40 * kentp 940314 Added possibility to not use messages
41 * rknier 940331 Added fast transfer code
42 * rknier 940407 Added assembler coded data transfers
43 *
027af0d8 44 * $Id: seagate.c,v 1.2 1994/06/13 02:49:12 sean Exp $
d7e75661
SV
45 */
46
47/*
48 * What should really be done:
49 *
50 * Add missing tests for timeouts
51 * Restructure interrupt enable/disable code (runs to long with int disabled)
52 * Find bug? giving problem with tape status
53 * Add code to handle Future Domain 840, 841, 880 and 881
54 * adjust timeouts (startup is very slow)
55 * add code to use tagged commands in SCSI2
56 * Add code to handle slow devices better (sleep if device not disconnecting)
57 * Fix unnecessary interrupts
58 */
59
60/* Note to users trying to share a disk between DOS and unix:
61 * The ST01/02 is a translating host-adapter. It is not giving DOS
62 * the same number of heads/tracks/sectors as specified by the disk.
63 * It is therefore important to look at what numbers DOS thinks the
64 * disk has. Use these to disklabel your disk in an appropriate manner
65 */
66
67#include <sys/types.h>
68
69#ifdef KERNEL /* don't laugh.. look for main() */
70#include <sea.h>
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/errno.h>
75#include <sys/ioctl.h>
76#include <sys/malloc.h>
77#include <sys/buf.h>
78#include <sys/proc.h>
79#include <sys/user.h>
80#include <i386/isa/isa_device.h>
81#endif /* KERNEL */
82#include <scsi/scsi_all.h>
83#include <scsi/scsiconf.h>
84
85#ifdef KERNEL
86#include "ddb.h"
87#include "kernel.h"
88#else /* KERNEL */
89#define NSEA 1
90#endif /* KERNEL */
91
92extern int hz;
93
94#define SEA_SCB_MAX 8 /* allow maximally 8 scsi control blocks */
95#define SCB_TABLE_SIZE 8 /* start with 8 scb entries in table */
96#define BLOCK_SIZE 512 /* size of READ/WRITE areas on SCSI card */
97
98/*
99 * defining PARITY causes parity data to be checked
100 */
101#define PARITY 1
102
103/*
104 * defining SEA_BLINDTRANSFER will make DATA IN and DATA OUT to be done with
105 * blind transfers, i.e. no check is done for scsi phase changes. This will
106 * result in data loss if the scsi device does not send its data using
107 * BLOCK_SIZE bytes at a time.
108 * If SEA_BLINDTRANSFER defined and SEA_ASSEMBLER also defined will result in
109 * the use of blind transfers coded in assembler. SEA_ASSEMBLER is no good
110 * without SEA_BLINDTRANSFER defined.
111 */
112#define SEA_BLINDTRANSFER 1 /* do blind transfers */
113#define SEA_ASSEMBLER 1 /* Use assembly code for fast transfers */
114
115/*
116 * defining SEANOMSGS causes messages not to be used (thereby disabling
117 * disconnects)
118 */
119/* #define SEANOMSGS 1 */
120
121/*
122 * defining SEA_NODATAOUT makes dataout phase being aborted
123 */
124/* #define SEA_NODATAOUT 1 */
125
126/*
127 * defining SEA_SENSEFIRST make REQUEST_SENSE opcode to be placed first
128 */
129/* #define SEA_SENSEFIRST 1 */
130
131#define SEA_FREEBSD11 1 /* intermediate def. for FreeBSD 1.1 BETA */
132 /* timeout function has changed */
133
134/* Debugging definitions. Should not be used unless you want a lot of
135 printouts even under normal conditions */
136
137/* #define SEADEBUG 1 */ /* General info about errors */
138/* #define SEADEBUG1 1 */ /* Info about internal results and errors */
139/* #define SEADEBUG2 1 */ /* Display a lot about timeouts etc */
140/* #define SEADEBUG3 1 */
141/* #define SEADEBUG4 1 */
142/* #define SEADEBUG5 1 */
143/* #define SEADEBUG6 1 */ /* Display info about queue-lengths */
144/* #define SEADEBUG7 1 */ /* Extra check on STATUS before phase check */
145/* #define SEADEBUG8 1 */ /* Disregard non-BSY state in
146 sea_information_transfer */
147/* #define SEADEBUG9 1 */ /* Enable printouts */
148/* #define SEADEBUG11 1 */ /* stop everything except access to scsi id 1 */
149/* #define SEADEBUG15 1 */ /* Display every byte sent/received */
150
151#define NUM_CONCURRENT 1 /* number of concurrent ops per board */
152
153/******************************* board definitions **************************/
154/*
155 * CONTROL defines
156 */
157
158#define CMD_RST 0x01 /* scsi reset */
159#define CMD_SEL 0x02 /* scsi select */
160#define CMD_BSY 0x04 /* scsi busy */
161#define CMD_ATTN 0x08 /* scsi attention */
162#define CMD_START_ARB 0x10 /* start arbitration bit */
163#define CMD_EN_PARITY 0x20 /* enable scsi parity generation */
164#define CMD_INTR 0x40 /* enable scsi interrupts */
165#define CMD_DRVR_ENABLE 0x80 /* scsi enable */
166
167/*
168 * STATUS
169 */
170
171#define STAT_BSY 0x01 /* scsi busy */
172#define STAT_MSG 0x02 /* scsi msg */
173#define STAT_IO 0x04 /* scsi I/O */
174#define STAT_CD 0x08 /* scsi C/D */
175#define STAT_REQ 0x10 /* scsi req */
176#define STAT_SEL 0x20 /* scsi select */
177#define STAT_PARITY 0x40 /* parity error bit */
178#define STAT_ARB_CMPL 0x80 /* arbitration complete bit */
179
180/*
181 * REQUESTS
182 */
183
184#define REQ_MASK (STAT_CD | STAT_IO | STAT_MSG)
185#define REQ_DATAOUT 0
186#define REQ_DATAIN STAT_IO
187#define REQ_CMDOUT STAT_CD
188#define REQ_STATIN (STAT_CD | STAT_IO)
189#define REQ_MSGOUT (STAT_MSG | STAT_CD)
190#define REQ_MSGIN (STAT_MSG | STAT_CD | STAT_IO)
191
192#define REQ_UNKNOWN 0xff
193
194#define SEAGATERAMOFFSET 0x00001800
195
196#ifdef PARITY
197 #define BASE_CMD (CMD_EN_PARITY | CMD_INTR)
198#else
199 #define BASE_CMD (CMD_INTR)
200#endif
201
202#define SEAGATE 1
203#define FD 2
204
205/******************************************************************************
206 * This should be placed in a more generic file (presume in /sys/scsi)
207 * Message codes:
208 */
209#define MSG_ABORT 0x06
210#define MSG_NOP 0x08
211#define MSG_COMMAND_COMPLETE 0x00
212#define MSG_DISCONNECT 0x04
213#define MSG_IDENTIFY 0x80
214#define MSG_BUS_DEV_RESET 0x0c
215#define MSG_MESSAGE_REJECT 0x07
216#define MSG_SAVE_POINTERS 0x02
217#define MSG_RESTORE_POINTERS 0x03
218/******************************************************************************/
219
220#define IDENTIFY(can_disconnect,lun) (MSG_IDENTIFY | ((can_disconnect) ? \
221 0x40 : 0) | ((lun) & 0x07))
222
223/* scsi control block used to keep info about a scsi command */
224struct sea_scb
225{
226 int flags; /* status of the instruction */
227#define SCB_FREE 0
228#define SCB_ACTIVE 1
229#define SCB_ABORTED 2
230#define SCB_TIMEOUT 4
231#define SCB_ERROR 8
232#define SCB_TIMECHK 16 /* We have set a timeout on this one */
233 struct sea_scb *next; /* in free list */
234 struct scsi_xfer *xfer; /* the scsi_xfer for this cmd */
235 u_char * data; /* position in data buffer so far */
236 int32 datalen; /* bytes remaining to transfer */;
237};
238
239/*
240 * data structure describing current status of the scsi bus. One for each
241 * controller card.
242 */
243struct sea_data
244{
245 caddr_t basemaddr; /* Base address for card */
246 char ctrl_type; /* FD or SEAGATE */
247 caddr_t st0x_cr_sr; /* Address of control and status register */
248 caddr_t st0x_dr; /* Address of data register */
249 u_short vect; /* interrupt vector for this card */
250 int our_id; /* our scsi id */
251 int numscb; /* number of scsi control blocks */
252 struct scsi_link sc_link; /* struct connecting different data */
253 struct sea_scb *connected; /* currently connected command */
254 struct sea_scb *issue_queue; /* waiting to be issued */
255 struct sea_scb *disconnected_queue; /* waiting to reconnect */
256 struct sea_scb scbs[SCB_TABLE_SIZE];
257 struct sea_scb *free_scb; /* free scb list */
258 volatile unsigned char busy[8]; /* index=target, bit=lun, Keep track of
259 busy luns at device target */
260} *seadata[NSEA];
261
262/* flag showing if main routine is running. */
263static volatile int main_running = 0;
264
265#define STATUS (*(volatile unsigned char *) sea->st0x_cr_sr)
266#define CONTROL STATUS
267#define DATA (*(volatile unsigned char *) sea->st0x_dr)
268
269/*
270 * These are "special" values for the tag parameter passed to sea_select
271 * Not implemented right now.
272 */
273
274#define TAG_NEXT -1 /* Use next free tag */
275#define TAG_NONE -2 /*
276 * Establish I_T_L nexus instead of I_T_L_Q
277 * even on SCSI-II devices.
278 */
279
280typedef struct {
281 char *signature ;
282 unsigned offset;
283 unsigned length;
284 unsigned char type;
285} BiosSignature;
286
287/*
288 * Signatures for automatic recognition of board type
289 */
290
291static const BiosSignature signatures[] = {
292{"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
293{"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
294
295/*
296 * The following two lines are NOT mistakes. One detects ROM revision
297 * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter,
298 * and this is not going to change, the "SEAGATE" and "SCSI" together
299 * are probably "good enough"
300 */
301
302{"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
303{"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
304
305 /*
306 * However, future domain makes several incompatible SCSI boards, so specific
307 * signatures must be used.
308 */
309
310 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 45, FD},
311 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
312 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
313 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
314 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
315 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
316 {"FUTURE DOMAIN TMC-950", 5, 21, FD},
317 };
318
319#define NUM_SIGNATURES (sizeof(signatures) / sizeof(BiosSignature))
320
321static const char * seagate_bases[] = {
322 (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
323 (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
324};
325
326#define NUM_BASES (sizeof(seagate_bases)/sizeof(char *))
327
328int sea_probe(struct isa_device *dev);
329int sea_attach(struct isa_device *dev);
330int seaintr(int unit);
331int32 sea_scsi_cmd(struct scsi_xfer *xs);
332#ifdef SEA_FREEBSD11
333void sea_timeout(caddr_t, int);
334#else
335void sea_timeout(struct sea_scb *scb);
336#endif
337void seaminphys(struct buf *bp);
338void sea_done(int unit, struct sea_scb *scb);
339u_int32 sea_adapter_info(int unit);
340struct sea_scb *sea_get_scb(int unit, int flags);
341void sea_free_scb(int unit, struct sea_scb *scb, int flags);
342static void sea_main(void);
343static void sea_information_transfer(struct sea_data *sea);
344int sea_poll(int unit, struct scsi_xfer *xs, struct sea_scb *scb);
345int sea_init(int unit);
346int sea_send_scb(struct sea_data *sea, struct sea_scb *scb);
347int sea_reselect(struct sea_data *sea);
348int sea_select(struct sea_data *sea, struct sea_scb *scb);
349int sea_transfer_pio(struct sea_data *sea, u_char *phase, int32 *count,
350 u_char **data);
351int sea_abort(int unit, struct sea_scb *scb);
352
353static sea_unit = 0;
354static sea_slot = -1; /* last found board seagate_bases address index */
355#define FAIL 1
356#define SUCCESS 0
357
358#ifdef KERNEL
359struct scsi_adapter sea_switch =
360{
361 sea_scsi_cmd,
362 seaminphys,
363 0,
364 0,
365 sea_adapter_info,
366 "sea",
367 0,0
368};
369
370/* the below structure is so we have a default dev struct for our link struct */
371struct scsi_device sea_dev =
372{
373 NULL, /* use default error handler */
374 NULL, /* have a queue, served by this */
375 NULL, /* have no async handler */
376 NULL, /* Use default 'done' routine */
377 "sea",
378 0,
379 0,0
380};
381
382struct isa_driver seadriver =
383{
9b3b13e5
SV
384 sea_probe,
385 sea_attach,
d7e75661
SV
386 "sea"
387};
388
389#endif /* KERNEL */
390
391#ifdef SEADEBUG6
392void sea_queue_length()
393{
394 struct sea_scb *tmp;
395 int length = 0;
396
397 if(seadata[0]->connected)
398 length = 1;
399 for(tmp = seadata[0]->issue_queue; tmp != NULL; tmp = tmp->next, length++);
400 for(tmp = seadata[0]->disconnected_queue ; tmp != NULL; tmp->next, length++);
401 printf("length:%d ",length);
402}
403#endif
404
405/***********************************************************************\
406* Check if the device can be found at the port given and if so, detect *
407* the type of board. Set it up ready for further work. Takes the *
408* isa_dev structure from autoconf as an argument. *
409* Returns 1 if card recognized, 0 if errors *
410\***********************************************************************/
411int
412sea_probe(dev)
413struct isa_device *dev;
414{
415 int j;
416 int unit = sea_unit;
417 struct sea_data *sea;
418 dev->id_unit = unit;
419
420#ifdef SEADEBUG2
421 printf("sea_probe ");
422#endif
423
424 /* find unit and check we have that many defined */
425 if(unit >= NSEA) {
426 printf("sea%d: unit number too high\n",unit);
427 return(0);
428 }
429 dev->id_unit = unit;
430#ifdef SEADEBUG2
431 printf("unit: %d\n",unit);
432 printf("dev_addr: 0x%lx\n",dev->id_maddr);
433#endif
434 /* allocate a storage area for us */
435
436 if (seadata[unit]) {
437 printf("sea%d: memory already allocated\n", unit);
438 return(0);
439 }
440#ifdef SEADEBUG2
441 printf("Before malloc\n");
442#endif
443 sea = malloc(sizeof(struct sea_data), M_TEMP, M_NOWAIT);
444 if (!sea) {
445 printf("sea%d: cannot malloc!\n", unit);
446 return(0);
447 }
448
449#ifdef SEADEBUG2
450 printf("after malloc\n");
451 for(j=0;j<32767;j++);
452#endif
453 bzero(sea,sizeof(struct sea_data));
454 seadata[unit] = sea;
455
456 /* check for address if no one specified */
457 sea->basemaddr = NULL;
458
459 /* Could try to find a board by looking through all possible addresses */
460 /* This is not done the right way now, because I have not found a way */
461 /* to get a boards virtual memory address given its physical. There is */
462 /* a function that returns the physical address for a given virtual */
463 /* address, but not the other way around */
464
465 if(dev->id_maddr == 0) {
466/*
467 for(sea_slot++;sea_slot<NUM_BASES;sea_slot++)
468 for(j = 0; !sea->basemaddr && j < NUM_SIGNATURES; ++j)
469 if(!memcmp((void *)(seagate_bases[sea_slot]+signatures[j].offset),
470 (void *) signatures[j].signature, signatures[j].length)) {
471 sea->basemaddr = (void *)seagate_bases[sea_slot];
472 break;
473 }
474*/
475 } else {
476
477#ifdef SEADEBUG2
478 printf("id_maddr != 0\n");
479 for(j = 0; j < 32767 ; j++);
480 for(j = 0; j < 32767 ; j++);
481#endif
482 /* find sea_slot position for overridden memory address */
483 for(j = 0; ((char *)vtophys(dev->id_maddr) != seagate_bases[j]) &&
484 j<NUM_BASES; ++j);
485 if(j == NUM_BASES) {
486 printf("sea: board not expected at address 0x%lx\n",dev->id_maddr);
487 seadata[unit]=NULL;
488 free(sea, M_TEMP);
489 return(0);
490 } else if(sea_slot > j) {
491 printf("sea: board address 0x%lx already probed!\n", dev->id_maddr);
492 seadata[unit]=NULL;
493 free(sea, M_TEMP);
494 return(0);
495 } else {
496 sea->basemaddr = dev->id_maddr;
497 }
498
499 }
500#ifdef SEADEBUG2
501 printf("sea->basemaddr = %lx\n", sea->basemaddr);
502#endif
503
504 /* check board type */ /* No way to define this through config */
505 for(j = 0; j < NUM_SIGNATURES; j++)
506 if(!memcmp((void *) (sea->basemaddr + signatures[j].offset),
507 (void *) signatures[j].signature, signatures[j].length)) {
508 sea->ctrl_type = signatures[j].type;
509 break;
510 }
511 if(j == NUM_SIGNATURES) {
512 printf("sea: Board type unknown at address 0x%lx\n",
513 sea->basemaddr);
514 seadata[unit]=NULL;
515 free(sea, M_TEMP);
516 return(0);
517 }
518
519 /* Find controller and data memory addresses */
520 sea->st0x_cr_sr = (void *) (((unsigned char *) sea->basemaddr) +
521 ((sea->ctrl_type == SEAGATE) ? 0x1a00 : 0x1c00));
522 sea->st0x_dr = (void *) (((unsigned char *) sea->basemaddr) +
523 ((sea->ctrl_type == SEAGATE) ? 0x1c00 : 0x1e00));
524
525 /* Test controller RAM (works the same way on future domain cards?) */
526 *(sea->basemaddr + SEAGATERAMOFFSET) = 0xa5;
527 *(sea->basemaddr + SEAGATERAMOFFSET + 1) = 0x5a;
528
529 if((*(sea->basemaddr + SEAGATERAMOFFSET) != (char) 0xa5) ||
530 (*(sea->basemaddr + SEAGATERAMOFFSET + 1) != (char) 0x5a)) {
531 printf("sea%d: Board RAM failure\n",unit);
532 }
533
534 if(sea_init(unit) != 0) {
535 seadata[unit] = NULL;
536 free(sea,M_TEMP);
537 return(0);
538 }
539
540 /* if its there put in it's interrupt vector */
541 /* (Doesn't use dma, so no drq is set) */
542 sea->vect = dev->id_irq;
543
544 sea_unit++;
545 return(1);
546}
547
548/***********************************************\
549* Attach all sub-devices we can find *
550\***********************************************/
551int
552sea_attach(dev)
553 struct isa_device *dev;
554{
555 int unit = dev->id_unit;
556 struct sea_data *sea = seadata[unit];
557
558#ifdef SEADEBUG2
559 printf("sea_attach called\n");
560#endif
561
562 /* fill in the prototype scsi_link */
563 sea->sc_link.adapter_unit = unit;
564 sea->sc_link.adapter_targ = sea->our_id;
565 sea->sc_link.adapter = &sea_switch;
566 sea->sc_link.device = &sea_dev;
567
568 /*****************************************************\
569 * ask the adapter what subunits are present *
570 \*****************************************************/
571 scsi_attachdevs(&(sea->sc_link));
572 return 1;
573}
574
575/***********************************************\
576* Return some information to the caller about *
577* the adapter and its capabilities *
578\***********************************************/
579u_int32
580sea_adapter_info(unit)
581 int unit;
582{
583#ifdef SEADEBUG2
584 printf("sea_adapter_info called\n");
585#endif
586 return 1;
587}
588
589/***********************************************\
590* Catch an interrupt from the adaptor *
591\***********************************************/
592int
593seaintr(unit)
594 int unit;
595{
596 int done;
597 struct sea_data *sea = seadata[unit];
598 int oldpri;
599
600#if SEADEBUG2
601 printf(";");
602#endif
603
604 do {
605 done = 1;
606 /* dispatch to appropriate routine if found and done=0 */
607 /* should check to see that this card really caused the interrupt */
608 if ((STATUS & (STAT_SEL | STAT_IO)) == (STAT_SEL | STAT_IO)) {
609 /* Reselect interrupt */
610#ifdef SEADEBUG2
611 printf(";2");
612#endif
613 done = 0;
614/* enable_intr(); */ /* ?? How should this be done ?? */
615 sea_reselect(sea);
616 } else if (STATUS & STAT_PARITY) {
617 /* Parity error interrupt */
618#ifdef SEADEBUG2
619 printf(";3");
620#endif
621 printf("sea%d: PARITY interrupt\n", unit);
622 } else {
623#ifdef SEADEBUG2
624/* printf("sea%d: unknown interrupt\n",unit); */
625 printf(";4%x", STATUS);
626#endif
627 }
628 if (!done) {
629 oldpri = splbio(); /* disable_intr(); */
630 if (!main_running) {
631#ifdef SEADEBUG2
632 printf(";5");
633#endif
634 main_running = 1;
635 sea_main();
636 /* main_running is cleared in sea_main once it can't
637 * do more work, and sea_main exits with interrupts
638 * disabled
639 */
640 splx(oldpri); /* enable_intr(); */
641 } else {
642 splx(oldpri); /* enable_intr(); */
643 }
644 }
645 } while (!done);
646 return 1;
647}
648
649/***********************************************\
650* Setup data structures, and reset the board *
651* and the scsi bus *
652\***********************************************/
653int
654sea_init(unit)
655 int unit;
656{
657 long l;
658 int i;
659 struct sea_data *sea = seadata[unit];
660
661#ifdef SEADEBUG2
662 printf("sea_init called\n");
663#endif
664/* Reset the scsi bus (I don't know if this is needed */
665 CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_RST;
666 DELAY(25); /* hold reset for at least 25 microseconds */
667 CONTROL = BASE_CMD;
668 DELAY(10); /* wait a Bus Clear Delay (800 ns + bus free delay (800 ns) */
669 /* Set our id (don't know anything about this) */
670 if(sea->ctrl_type == SEAGATE)
671 sea->our_id = 7;
672 else
673 sea->our_id = 6;
674 /* init fields used by our routines */
675 sea->connected = NULL;
676 sea->issue_queue = NULL;
677 sea->disconnected_queue = NULL;
678 for (i=0; i<8 ; i++)
679 sea->busy[i] = 0;
680
681 /* link up the free list of scbs */
682 sea->numscb = SCB_TABLE_SIZE;
683 sea->free_scb = (struct sea_scb *) & (sea->scbs[0]);
684 for(i=1;i< SCB_TABLE_SIZE ; i++) {
685 sea->scbs[i-1].next = &(sea->scbs[i]);
686 }
687 sea->scbs[SCB_TABLE_SIZE - 1].next = NULL;
688
689 return(0);
690}
691
692/***********************************************\
693* *
694\***********************************************/
695void seaminphys(bp)
696 struct buf *bp;
697{
698#ifdef SEADEBUG2
699/* printf("seaminphys called\n"); */
700 printf(",");
701#endif
702}
703
704/***********************************************\
705* start a scsi operation given the command and *
706* the data address. Also needs the unit, target *
707* and lu *
708* get a free scb and set it up *
709* call send_scb *
710* either start timer or wait until done *
711\***********************************************/
712int32 sea_scsi_cmd(xs)
713struct scsi_xfer *xs;
714{
715 struct scsi_sense_data *s1, *s2;
716 struct sea_scb *scb;
717 int i = 0;
718 int flags;
719 int unit = xs->sc_link->adapter_unit;
720 struct sea_data *sea = seadata[unit];
721 int s;
722 unsigned int stat;
723 int32 result;
724
725#ifdef SEADEBUG2
726 /* printf("scsi_cmd\n"); */
727 printf("=");
728#endif
729
730#ifdef SEADEBUG11
731 if(xs->sc_link->target != 1) {
732 xs->flags |= ITSDONE;
733 xs->error = XS_TIMEOUT;
734 return(HAD_ERROR);
735 }
736#endif
737
738 flags = xs->flags;
739 if(xs->bp) flags |= (SCSI_NOSLEEP);
740 if(flags & ITSDONE) {
741 printf("sea%d: Already done?", unit);
742 xs->flags &= ~ITSDONE;
743 }
744 if(!(flags & INUSE)) {
745 printf("sea%d: Not in use?", unit);
746 xs->flags |= INUSE;
747 }
748 if (!(scb = sea_get_scb(unit, flags))) {
749#ifdef SEADEBUG2
750 printf("=2");
751#endif
752 xs->error = XS_DRIVER_STUFFUP;
753 return(TRY_AGAIN_LATER);
754 }
755
756 /*
757 * Put all the arguments for the xfer in the scb
758 */
759 scb->xfer = xs;
760 scb->datalen = xs->datalen;
761 scb->data = xs->data;
762
763 if(flags & SCSI_RESET) {
764 /* Try to send a reset command to the card. This is done by calling the
765 * Reset function. Should then return COMPLETE. Need to take care of the
766 * possible current connected command.
767 * Not implemented right now.
768 */
769 printf("sea%d: Got a SCSI_RESET!\n",unit);
770 }
771
772 /* setup the scb to contain necessary values */
773 /* The interresting values can be read from the xs that is saved */
774 /* I therefore think that the structure can be kept very small */
775 /* the driver doesn't use DMA so the scatter/gather is not needed ? */
776#ifdef SEADEBUG6
777 sea_queue_length();
778#endif
779 if (sea_send_scb(sea, scb) == 0) {
780#ifdef SEADEBUG2
781 printf("=3");
782#endif
783 xs->error = XS_DRIVER_STUFFUP;
784 sea_free_scb(unit, scb, flags);
785 return (TRY_AGAIN_LATER);
786 }
787
788 /*
789 * Usually return SUCCESSFULLY QUEUED
790 */
791 if (!(flags & SCSI_NOMASK)) {
792 if(xs->flags & ITSDONE) { /* timout timer not started, already finished */
793 /* Tried to return COMPLETE but the machine hanged with this */
794#ifdef SEADEBUG2
795 printf("=6");
796#endif
797 return(SUCCESSFULLY_QUEUED);
798 }
799#ifdef SEA_FREEBSD11
800 timeout(sea_timeout, (caddr_t)scb, (xs->timeout * hz) / 1000);
801#else
802 timeout(sea_timeout, scb, (xs->timeout * hz) / 1000);
803#endif
804 scb->flags |= SCB_TIMECHK;
805#ifdef SEADEBUG2
806 printf("=4");
807#endif
808 return(SUCCESSFULLY_QUEUED);
809 }
810
811 /*
812 * If we can't use interrupts, poll on completion
813 */
814
815 result = sea_poll(unit, xs, scb);
816#ifdef SEADEBUG2
817 printf("=5 %lx", result);
818#endif
819 return result;
820}
821
822/*
823 * Get a free scb. If there are none, see if we can allocate a new one. If so,
824 * put it in the hash table too, otherwise return an error or sleep.
825 */
826
827struct sea_scb *
828sea_get_scb(unit, flags)
829 int unit;
830 int flags;
831{
832 struct sea_data *sea = seadata[unit];
833 unsigned opri = 0;
834 struct sea_scb * scbp;
835 int hashnum;
836
837#ifdef SEADEBUG2
838/* printf("get_scb\n"); */
839 printf("(");
840#endif
841
842 if (!(flags & SCSI_NOMASK))
843 opri = splbio();
844
845#ifdef SEADEBUG3
846 printf("(2 %lx ", sea->free_scb);
847#endif
848
849 /*
850 * If we can and have to, sleep waiting for one to come free
851