2 Copyright © 2004-2018, The AROS Development Team. All rights reserved.
3 $Id: lowlevel.c 55802 2019-03-08 21:47:59Z wawa $
11 * - put a critical section around DMA transfers (shared dma channels)
14 #include <aros/debug.h>
16 #include <proto/exec.h>
18 #include <exec/types.h>
19 #include <exec/exec.h>
20 #include <exec/resident.h>
21 #include <utility/utility.h>
24 #include <devices/timer.h>
30 // use #define xxx(a) D(a) to enable particular sections.
37 #define DATAPI(a) D(a)
40 #define DIRQ(a) do { } while (0)
41 #define DIRQ_MORE(a) do { } while (0)
42 #define DUMP(a) do { } while (0)
43 #define DUMP_MORE(a) do { } while (0)
44 #define DSCSI(a) do { } while (0)
45 #define DATAPI(a) do { } while (0)
48 /* Errors that shouldn't happen */
52 * Initial device configuration that suits *all* cases
54 void scsi_init_unit(struct scsi_Bus
*bus
, struct scsi_Unit
*unit
, UBYTE u
)
56 struct scsiBase
*SCSIBase
= bus
->sb_Base
;
57 OOP_Object
*obj
= OOP_OBJECT(SCSIBase
->busClass
, bus
);
60 unit
->pioInterface
= bus
->pioInterface
;
61 unit
->su_UnitNum
= bus
->sb_BusNum
<< 1 | u
; // b << 8 | u
62 unit
->su_DevMask
= 0xa0 | (u
<< 4);
64 DINIT(bug("[SCSI%02u] scsi_init_unit: bus %u unit %d\n", unit
->su_UnitNum
, bus
->sb_BusNum
, u
));
67 /* Set PIO transfer functions, either 16 or 32 bits */
68 if (SCSIBase
->scsi_32bit
&& OOP_GET(obj
, aHidd_SCSIBus_Use32Bit
))
69 Unit_Enable32Bit(unit
);
71 Unit_Disable32Bit(unit
);
75 BOOL
scsi_setup_unit(struct scsi_Bus
*bus
, struct scsi_Unit
*unit
)
78 * this stuff always goes along the same way
79 * WARNING: NO INTERRUPTS AT THIS POINT!
83 DINIT(bug("[SCSI ] scsi_setup_unit(%d)\n", unit
->su_UnitNum
));
85 scsi_SelectUnit(unit
);
87 if (FALSE
== scsi_WaitBusyTO(unit
, 1, FALSE
, FALSE
, NULL
))
89 DINIT(bug("[SCSI%02ld] scsi_setup_unit: ERROR: Drive not ready for use. Keeping functions stubbed\n", unit
->su_UnitNum
));
93 u
= unit
->su_UnitNum
& 1;
94 switch (bus
->sb_Dev
[u
])
97 * safe fallback settings
103 unit
->su_Identify
= scsi_Identify
;
107 DINIT(bug("[SCSI%02ld] scsi_setup_unit: Unsupported device %lx. All functions will remain stubbed.\n", unit
->su_UnitNum
, bus
->sb_Dev
[u
]));
111 DINIT(bug("[SCSI ] scsi_setup_unit: Enabling IRQs\n"));
112 PIO_OutAlt(bus
, 0x0, scsi_AltControl
);
115 * now make unit self diagnose
117 if (unit
->su_Identify(unit
) != 0)
126 void scsi_InitBus(struct scsi_Bus
*bus
)
128 struct scsiBase
*SCSIBase
= bus
->sb_Base
;
129 OOP_Object
*obj
= OOP_OBJECT(SCSIBase
->busClass
, bus
);
135 * initialize timer for the sake of scanning
137 bus
->sb_Timer
= scsi_OpenTimer(bus
->sb_Base
);
140 OOP_GetAttr(obj
, aHidd_SCSIBus_UseIOAlt
, &haveAltIO
);
141 bus
->haveAltIO
= haveAltIO
!= 0;
144 DINIT(bug("[SCSI ] scsi_InitBus(%p)\n", bus
));
146 bus
->sb_Dev
[0] = DEV_NONE
;
147 bus
->sb_Dev
[1] = DEV_NONE
;
149 /* Check if device 0 and/or 1 is present on this bus. It may happen that
150 a single drive answers for both device addresses, but the phantom
151 drive will be filtered out later */
152 for (i
= 0; i
< MAX_BUSUNITS
; i
++)
154 /* Select device and disable IRQs */
156 PIO_Out(bus
, DEVHEAD_VAL
| (i
<< 4), scsi_DevHead
);
158 scsi_WaitTO(bus
->sb_Timer
, 0, 400, 0);
159 PIO_OutAlt(bus
, SCSICTLF_INT_DISABLE
, scsi_AltControl
);
161 /* Write some pattern to registers. This is a variant of a more
162 common technique, with the difference that we don't use the
163 sector count register because some bad ATAPI drives disallow
165 PIO_Out(bus
, 0x55, scsi_LBALow
);
166 PIO_Out(bus
, 0xaa, scsi_LBAMid
);
167 PIO_Out(bus
, 0xaa, scsi_LBALow
);
168 PIO_Out(bus
, 0x55, scsi_LBAMid
);
169 PIO_Out(bus
, 0x55, scsi_LBALow
);
170 PIO_Out(bus
, 0xaa, scsi_LBAMid
);
172 tmp1
= PIO_In(bus
, scsi_LBALow
);
173 tmp2
= PIO_In(bus
, scsi_LBAMid
);
174 DB2(bug("[SCSI ] scsi_InitBus: Reply 0x%02X 0x%02X\n", tmp1
, tmp2
));
176 if ((tmp1
== 0x55) && (tmp2
== 0xaa))
177 bus
->sb_Dev
[i
] = DEV_UNKNOWN
;
178 DINIT(bug("[SCSI ] scsi_InitBus: Device type = 0x%02X\n", bus
->sb_Dev
[i
]));
183 scsi_CloseTimer(bus
->sb_Timer
);
184 DINIT(bug("[SCSI ] scsi_InitBus: Finished\n"));