home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/resident.h>
- #include <exec/memory.h>
- #include <exec/devices.h>
- #include <libraries/expansionbase.h>
- #include <libraries/configvars.h>
-
- /*
- * Set SysBase to a local variable, that loads directly from 4 when it
- * has to be reloaded
- */
- #define BASE_EXT_DECL
- #define BASE_NAME (*(void **)4)
- #include <inline/exec.h>
-
- #include "device.h"
-
- /*
- * Check a given scsi unit for an attached device.
- */
-
- extern void unit_start(struct scsi_unit *unit);
- DECL_DPRINTF;
-
- void
- try_unit(struct scsi_dev *dev, int unit)
- {
- /* this checks, whether an scsi-device responds to the given
- * unit number.
- * if there is a unit responding, a unit task is created */
- ubyte cmd[12];
- struct scsi_msg *sc = &dev->sc_hmessage;
- struct SCSICmd scd;
- ulong sense_buf;
- struct scsi_unit *su;
- struct Task *tcb;
- int retries;
-
- dev->sc_units[unit] = 0;
-
- #ifdef DEBUG
- /* if (unit != 2 && unit != 4) return;*/
- #endif
-
- sc->scm_message.mn_ReplyPort = &dev->sc_msgport;
-
- /* first do a TEST UNIT READY, if there is no device of that unit
- * the answer will be a select-timeout */
-
- cmd[0] = cmd[1] = cmd[2] = cmd[3] = cmd[4] = cmd[5] = 0;
- sc->scm_scsi_cmd = &scd;
-
- scd.scsi_Length = 0;
- scd.scsi_Command = cmd;
- scd.scsi_CmdLength = 6;
- /* swallow any UNIT ATTENTION responses */
- scd.scsi_Flags = SCSIF_READ|SCSIF_OLDAUTOSENSE;
- scd.scsi_SenseData = (UBYTE *)&sense_buf;
- scd.scsi_SenseLength = 4;
-
- retries = 60;
- do
- {
- sc->scm_cmd = SCM_CMD_EXEC_SCSI;
- sc->scm_unit = unit;
-
- PutGetMsg(dev->sc_hmsgport, &dev->sc_msgport, (struct Message *)sc);
- }
- while ((sc->scm_cmd == HFERR_DMA || sc->scm_cmd == HFERR_Phase) && retries-- >= 0) ;
-
- /* in these two cases, a unit is attached to the bus, no matter
- * whether it is currently ready or not */
- if (sc->scm_cmd == 0 || sc->scm_cmd == HFERR_BadStatus)
- {
- /* now set up a task for this unit */
-
- DPRINTF(("unit %ld ok, starting unit task", unit));
-
- su = (struct scsi_unit *)AllocMem(sizeof(*su), MEMF_CLEAR|MEMF_PUBLIC);
- dev->sc_units[unit] = su;
-
- su->scu_unitnum = unit;
- su->scu_device = dev;
- su->scu_hmsgport = dev->sc_hmsgport;
- sc = &su->scu_hmessage;
-
- tcb = &su->scu_tcb;
- tcb->tc_SPLower = (APTR)su->scu_stack;
- tcb->tc_SPUpper = (APTR)(su->scu_stack + UNIT_STACKSIZE);
- tcb->tc_SPReg = (APTR)(tcb->tc_SPUpper - 4);
- /* pass the child the unit pointer */
- *(struct scsi_unit **)tcb->tc_SPReg = su;
-
- tcb->tc_Node.ln_Type = NT_TASK;
- tcb->tc_Node.ln_Pri = UNIT_PRIORITY;
- tcb->tc_Node.ln_Name = UNIT_NAME;
-
- NewList(&tcb->tc_MemEntry);
-
- AddTask(tcb, unit_start, 0);
-
- /* the unit now figures out itself, of which type it is */
- DPRINTF(("unit %ld TEST READY ok", unit));
- }
- else
- DPRINTF(("unit %ld TEST READY negativ", unit));
- }
-
-
-