Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac Plus won't boot with SCDP attached #419

Closed
jcs opened this issue Nov 5, 2021 · 21 comments
Closed

Mac Plus won't boot with SCDP attached #419

jcs opened this issue Nov 5, 2021 · 21 comments

Comments

@jcs
Copy link
Collaborator

jcs commented Nov 5, 2021

Info

  • Which version of Pi are you using:
    4B

  • Which github revision of software:
    cf9a578 (v21.10.01)

  • Which board version:
    FULLSPEC

  • Which computer is the RaSCSI connected to:
    Macintosh Plus

Describe the issue

When attaching a DaynaPort SCSI/Link ethernet device via rasctl before booting the Mac, the Mac won't boot similar to issue #40 where it shows a black screen. If the Mac is booted and the ethernet device is attached later, it works fine. This makes it difficult to use RaSCSI for both a hard drive (SCHD) and ethernet (SCDP), since the SCHD device has to be attached before booting but the ethernet has to be attached after a delay.

I'm assuming the Mac probes the SCSI bus during boot while looking for hard drives and gets a weird response from the ethernet device just like in #40 where the Lido driver caused issues.

Perhaps there's a way to detect this activity and just ignore the probe in the ethernet device driver...

@rdmark
Copy link
Member

rdmark commented Nov 5, 2021

@jcs This is definitely not how it should work. I tried to reproduce on my Mac SE, but without success, so it may be a quirk of the Plus's infamously non-standard SCSI interface.

Just to throw a couple of thoughts out there:
Do you know which driver your hard drive image is using (Lido etc.)? Have you tried another boot volume hard drive image? Have you tried different SCSI ID assignments and orders of devices?

@jcs
Copy link
Collaborator Author

jcs commented Nov 6, 2021

The issue happens without any hard drive image attached. If I boot to a floppy or HD20 with the ethernet device attached in RaSCSI it goes to the black screen.

@uweseimet
Copy link
Contributor

@jcs Please add rascsi trace logs to this ticket, based on the simplest scenario (no drives attached) you can reproduce this issue with.

@jcs
Copy link
Collaborator Author

jcs commented Nov 7, 2021

$ sudo rascsi -L trace
SCSI Target Emulator RaSCSI(*^..^*) version 21.10.1 (Nov  5 2021, 01:18:54)
Powered by XM6 TypeG Technology / Copyright (C) 2016-2020 GIMONS
Copyright (C) 2020-2021 Contributors to the RaSCSI project
Connect type : FULLSPEC
[2021-11-07 12:11:39.599] [info] No images currently attached.
No images currently attached.
[2021-11-07 12:11:41.321] [info] Validating: operation=ATTACH, device id=6, unit=0, type=SCDP, device params='file=wlan0:10.10.20.1/24', 'interfaces=wlan0:10.10.20.1/24', vendor='', product='', revision='', block size=0
[2021-11-07 12:11:41.321] [info] Executing: operation=ATTACH, device id=6, unit=0, type=SCDP, device params='file=wlan0:10.10.20.1/24', 'interfaces=wlan0:10.10.20.1/24', vendor='', product='', revision='', block size=0
[2021-11-07 12:11:41.322] [trace] Opening Tap device
[2021-11-07 12:11:41.322] [trace] Opened tap device 7
[2021-11-07 12:11:41.322] [trace] Going to open ras0
[2021-11-07 12:11:41.323] [trace] return code from ioctl was 0
[2021-11-07 12:11:41.323] [info] rascsi_bridge is already available
[2021-11-07 12:11:41.323] [debug] ip link set ras0 up
[2021-11-07 12:11:41.323] [debug] brctl addif rascsi_bridge ras0
[2021-11-07 12:11:41.325] [trace] Getting the MAC address
[2021-11-07 12:11:41.325] [trace] Got the MAC
[2021-11-07 12:11:41.325] [info] Tap device ras0 created
[2021-11-07 12:11:41.325] [debug] Tap interface created
[2021-11-07 12:11:41.325] [trace] virtual bool SCSIDaynaPort::Init(const std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&) memset(m_mac_addr, 0x00, 6);
[2021-11-07 12:11:41.326] [trace] virtual bool SCSIDaynaPort::Init(const std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&) m_mac_addr[0]=0x00;
[2021-11-07 12:11:41.328] [info] Attached SCDP device, ID 6, unit 0

[ Mac Plus is booted here ]

[2021-11-07 12:12:18.011] [trace] virtual void SCSIDEV::Selection() Selection Phase ID=6 (with device)
[2021-11-07 12:12:18.011] [trace] virtual void SASIDEV::Command() Command Phase
[2021-11-07 12:12:18.011] [trace] virtual void SASIDEV::Command() Command Byte 0: $08
[2021-11-07 12:12:18.011] [trace] virtual void SASIDEV::Command() Command Byte 1: $00
[2021-11-07 12:12:18.011] [trace] virtual void SASIDEV::Command() Command Byte 2: $00
[2021-11-07 12:12:18.012] [trace] virtual void SASIDEV::Command() Command Byte 3: $00
[2021-11-07 12:12:18.012] [trace] virtual void SASIDEV::Command() Command Byte 4: $01
[2021-11-07 12:12:18.012] [trace] virtual void SASIDEV::Command() Command Byte 5: $00
[2021-11-07 12:12:18.012] [trace] virtual void SCSIDEV::Execute() Execution phase command $08
[2021-11-07 12:12:18.012] [debug] ++++ CMD ++++ virtual void SCSIDEV::Execute() Executing command $08
[2021-11-07 12:12:18.012] [debug] virtual bool SCSIDaynaPort::Dispatch(SCSIDEV*) Executing Read6 ($08)
[2021-11-07 12:12:18.012] [trace] virtual void SCSIDaynaPort::Read6(SASIDEV*) READ(6) command record=0 blocks=1
[2021-11-07 12:12:18.012] [trace] virtual int SCSIDaynaPort::Read(const DWORD*, BYTE*, uint64_t) reading DaynaPort block 0
[2021-11-07 12:12:18.012] [trace] virtual int SCSIDaynaPort::Read(const DWORD*, BYTE*, uint64_t) Read maximum length 0, (0000)
[2021-11-07 12:12:18.013] [trace] BOOL CTapDriver::PendingPackets() 1 revents
[2021-11-07 12:12:18.013] [debug] int CTapDriver::Rx(BYTE*) CRC is 77C7F92E - 2E F9 C7 77
[2021-11-07 12:12:18.013] [trace] virtual int SCSIDaynaPort::Read(const DWORD*, BYTE*, uint64_t) Packet Sz 134 (00000086) read: 1
[2021-11-07 12:12:18.013] [trace] BOOL CTapDriver::PendingPackets() 1 revents
[2021-11-07 12:12:18.013] [trace] virtual void SCSIDaynaPort::Read6(SASIDEV*) ctrl.length is 140
[2021-11-07 12:12:18.013] [trace] void SASIDEV::DataIn() Going into Data-in Phase
[2021-11-07 12:12:18.013] [trace] virtual void SCSIDEV::Send() sending handhake with offset 0, length 140
[2021-11-07 12:12:18.014] [trace] virtual int GPIOBUS::SendHandShake(BYTE*, int, int) DELAYING for 100us after 6 bytes
[2021-11-07 12:12:18.015] [trace] virtual void SCSIDEV::Send() Move to next phase datain (6)
[2021-11-07 12:12:18.015] [trace] void SASIDEV::Status() Status phase
[2021-11-07 12:12:18.015] [trace] void SASIDEV::Status() Status Phase $00
[2021-11-07 12:12:18.015] [trace] virtual void SCSIDEV::Send() sending handhake with offset 0, length 1

[ Mac Plus screen has gone black ]

[2021-11-07 12:12:24.010] [trace] virtual void SCSIDEV::BusFree() Bus free phase

@uweseimet
Copy link
Contributor

uweseimet commented Nov 7, 2021

@jcs Thank you for the logs. Looks as if the driver does not check for the device type when booting but just treats the Daynaport like a hard disk drive and tries to read a sector from the Daynaport, using Read(6), which is a SCSI command for reading sectors. But for the Daynaport Read(6) reads packets, not sectors, and packets do not always have 512 bytes or a multiple of 512. In your log the Daynaport device as response to the read request returns 140 bytes, but the Mac expects 512 bytes, which it never gets. The Mac should notice that there are no more data because the SCSI status phase is entered, but it appears as if the Mac keeps on waiting.

Somebody with more insight into the Daynaport code might be able to tell more, but IMHO the problem is not caused by RaSCSI but by the Mac trying to read a sector from a non-hard disk device, and then not being able to cope with getting less data than expected, even though the SCSI bus signals indicate that all available data have been transferred.
Would be interesting to know what happens when a real Daynaport device is connected.

@rdmark
Copy link
Member

rdmark commented Nov 7, 2021

@jcs Have you installed the DaynaPort Mac driver, and which version? Also, which version of the System Software / Mac OS are you running?

@jcs
Copy link
Collaborator Author

jcs commented Nov 8, 2021

I have installed the Mac driver on the hard drive image I boot with, and it works fine as an ethernet device if it's attached after booting. But with both devices attached at boot, it never gets as far as booting from the hard drive image.

This is System 6.0.8.

jcs added a commit to jcs/RASCSI that referenced this issue Nov 8, 2021
The Mac Plus tries to read a sector from the DaynaPort device at
boot as if it were a hard drive.  If we send actual ethernet data
back, it causes a hang.

Until the DaynaPort driver on the Mac side has actually initialized
and enabled the interface, send back empty 512-byte responses to
READ(6) requests.

The Mac driver doesn't seem to actually disable the driver at
shutdown/reboot time though, so there will probably need to be a
better way to detect going back into the non-initialized state at
reboot time.

See issue PiSCSI#419
@jcs
Copy link
Collaborator Author

jcs commented Nov 8, 2021

Maybe something like cc68528fa could help. Until the Mac driver properly initializes the device, send back empty 512-byte responses. I would assume non-Mac-Plus devices won't do reads like this at boot until the driver initializes, and on the Mac Plus this will prevent it from trying to read bogus (ethernet) data as bootable code.

$ sudo ./bin/fullspec/rascsi 
SCSI Target Emulator RaSCSI(*^..^*) version 21.10.1 (Nov  8 2021, 01:35:27)
Powered by XM6 TypeG Technology / Copyright (C) 2016-2020 GIMONS
Copyright (C) 2020-2021 Contributors to the RaSCSI project
Connect type : FULLSPEC
[2021-11-08 01:39:32.422] [info] No images currently attached.
No images currently attached.
[2021-11-08 01:39:41.346] [info] Validating: operation=ATTACH, device id=6, unit=0, type=SCDP, device params='file=wlan0:10.10.20.1/24', 'interfaces=wlan0:10.10.20.1/24', vendor='', product='', revision='', block size=0
[2021-11-08 01:39:41.346] [info] Executing: operation=ATTACH, device id=6, unit=0, type=SCDP, device params='file=wlan0:10.10.20.1/24', 'interfaces=wlan0:10.10.20.1/24', vendor='', product='', revision='', block size=0
[2021-11-08 01:39:41.348] [info] rascsi_bridge is already available
[2021-11-08 01:39:41.353] [info] Tap device ras0 created
[2021-11-08 01:39:41.353] [info] Attached SCDP device, ID 6, unit 0
[2021-11-08 01:39:48.706] [info] Validating: operation=ATTACH, device id=0, unit=0, type=UNDEFINED, device params='file=/home/jcs/macplus.hda', 'interfaces=/home/jcs/macplus.hda', vendor='', product='', revision='', block size=0
[2021-11-08 01:39:48.707] [info] Executing: operation=ATTACH, device id=0, unit=0, type=UNDEFINED, device params='file=/home/jcs/macplus.hda', 'interfaces=/home/jcs/macplus.hda', vendor='', product='', revision='', block size=0
[2021-11-08 01:39:48.707] [info] Attached SCHD device, ID 0, unit 0
[ Up to this point, any READs just get returned an empty 512-byte block ]
[2021-11-08 01:40:51.395] [info] The DaynaPort interface has been ENABLED.
[ This was after MacTCP initialized and loaded the driver, so now we are actually sending back ethernet traffic ]

This lets my Mac Plus boot with the DaynaPort and hard drive devices attached before booting, though the driver doesn't seem to disable the device at reboot/shutdown time, so going back into the non-initialized state still needs some work to allow my Mac Plus to reboot properly.

@marciot
Copy link

marciot commented Nov 8, 2021

Just to chime in on this thread. I am able to confirm a black startup screen when powering up the Mac Plus with the SCDP.

Which version of Pi are you using: Rasp Pi Zero W
Which github revision of software: cf9a578 (v21.10.01)
Which board version: FULLSPEC
Which computer is the RaSCSI connected to: Macintosh Plus

I am using System 7.0.1.

I tried turning on the SCDP right after the system started booting and can confirm this is a viable workaround. However, at this point I am not able to establish at network connection. When I run the DynaPORT Hardware Diagnostics, the Mac immediately reboots. When I run the DynaPORT Software Diagnostics, it tells me to open Control Panels -> Network, but when I do so I get an error "The control panel Network could not be opened, because error type -39 occurred"

Other observations:

  • Even though I ran the DynaPORT Installer, I do not see any new Extensions or Control Panels in my System Folder. This seems peculiar.
  • SCSI Probe correctly reports the DynaPORT device.

@marciot
Copy link

marciot commented Nov 8, 2021

I was able to solve the error -39 by performing the steps in this exact order:

  • Do a clean reinstall of System 7.0.1
  • Copy the DynaPORT Installer to the disk
  • Reboot into the disk, enable SCDP right after the Happy Mac
  • Run the DynaPORT Installer program. The Easy Install should auto-detect the DynaPORT SCSI/Link.
  • Reboot, enable SCDP right after the Happy Mac
  • Open Control Panel -> Network
  • Select "EtherTalk Alternative"
  • Run "Software Diagnostics". It reports:
    • Ethernet Address: 00:80:19:10:98:e3
    • Zone Name: Not found
    • Node Number: 2
    • Network Number: Not Found
    • Driver Type and Version: DynaPORT SCSI/Link v1.2.5f
    • To Test Network Communications, Run SendEcho

When I run "SendEcho", it reports "No Zones". This is expected, as I have not configured the bridge device in RaSCSI at all, nor do I have another Mac on the network. I would like to setup Basillisk II as an AppleTalk server on my PC, as that would be mind-blowingly awesome, but that is a project for tomorrow.

So at this point, I have confirmed the following:

  • Mac Plus won't boot with SCDP attached (as this ticket describes)
  • Enabling SCDP right after Happy Mac is an alternative
  • Running "Hardware Diagnostics" reboots the Mac
  • Running "Software Diagnostics" works and reports correct information
  • Properly installing the DaynaPORT drivers does not seem to involve any extra control panels or extensions in the System Folder [Note 1]
  • The DynaPORT SCSI/Link drivers seem to work fine on System 7.0.1 if you install them in a particular order.

[Note 1] At one point, the installation failed and I found an "Installer Temp" directory with a System file in it, so I suspect the DaynaPORT Installer modifies the System file, which is why a clean install may be helpful.

@rdmark
Copy link
Member

rdmark commented Nov 8, 2021

@marciot I think the DaynaPort installer modifies Apple extensions in-place, rather than installing distinct extensions. At least as far as I can tell. BTW, I've also had luck with DaynaPort on both 7.0.1 and 6.0.7, but on an SE rather than a Plus.

And, somewhat off topic, you don't have to mess with Basilisk II to run an AppleShare server. Why don't you try installing Netatalk on your Pi in parallel with RaSCSI. I've even automated the process in easyinstall.sh ;)

@marciot
Copy link

marciot commented Nov 8, 2021

This lets my Mac Plus boot with the DaynaPort and hard drive devices attached before booting, though the driver doesn't seem to disable the device at reboot/shutdown time, so going back into the non-initialized state still needs some work to allow my Mac Plus to reboot properly.

I find that detaching the SCDP device in the RaSCSI web interface is all it takes to allow the Mac to boot. Maybe this is what you meant by "some work".

I have 4MB of RAM on my Plus, so it takes a relatively long time for the Mac to finish the memory test (with the diagonal lines on the screen). I find this is plenty of time to get ready to click the Attach or Detach on the SCDP device as needed. But for convenience, cf9a578 would be nice at startup, since this is the most timing critical bit.

@marciot
Copy link

marciot commented Nov 8, 2021

@rdmark: I saw somewhere in the RaSCSI documentation where it was not recommended to run RaSCSI and Netatalk on the Pi Zero due to performance limitations. Has this changed?

Anyhow, I am curious to hear your workflow, but I feel like running an AppleShare server on the Raspberry Pi itself would be of limited utility for me, as then I would have to get files out of Basillisk II and SFTP them over to the Raspberry Pi, maybe using .hqx or something to preserve the resource fork. Generally I like using Basillisk II to unpack archives, extract disk images and do all the fiddling with the files prior to sending them over to my Mac Plus. Right now I do this by mounting a disk image in Basillisk, modifying it, uploading it to the RaspPI, and mounting it on the Mac Plus. I think if my Basillisk II was an AppleTalk server, I would be able to simply copy the extracted files into the server directory and have them show up on my Mac Plus. That would be amazing!

@rdmark
Copy link
Member

rdmark commented Nov 8, 2021

@marciot To give you a short answer: I also like to use Basilisk in the way that you describe. Basilisk II is able to connect to the same Netatalk server (over TCP only) running on the Pi. Netatalk is smart enough to save the resource fork on the Linux file system as separate files, and then merge them back together when copying back to a Mac. It works totally seamlessly.

But yeah, the Zero might struggle. Maybe you can run it on another Linux machine (or VM).

Anyhow, let's stop getting off topic here. The https://tinkerdifferent.com/ forums could be a good place for these topics!

@uweseimet
Copy link
Contributor

uweseimet commented Nov 8, 2021

@jcs Instead of returning dummy data (which may cause issues with other drivers and does not look like a clean solution) in jcs@cc68528, does it also work if you report a proper SCSI error instead, e.g. DEVICE NOT READY? After all, that's what it is, if you want to access a device that is not initialized yet. I'm quite sure the Mac will react correctly on this, because the same can happen if a removable media drive, e.g. a ZIP without media, is present.
One more thing: The comments in scsi_daynaport.cpp say that for the READ command the last byte of the CDB has to be c0 or 80:

//	READ
//
//   Command:  08 00 00 LL LL XX (LLLL is data length, XX = c0 or 80)
//   Function: Read a packet at a time from the device (standard SCSI Read)

If this comment is correct, the command sent by the Mac when booting is invalid (for the Daynaport), because the last byte of the CDB is 0. If it is really the case that "regular" Daynaport read commands always have c0 or 80 as the last byte in the CDB (you should be able to see this in the trace logs when using the network), one could properly reject a READ command with 0 as the last CDB byte with a SCSI error INVALID FIELD IN CDB.

@jcs
Copy link
Collaborator Author

jcs commented Nov 8, 2021

Thanks @uweseimet, returning ERROR_CODES::sense_key::NOT_READY in SCSIDaynaPort::Read6 works well for the Mac Plus. I'll look into checking the CDB byte.

@uweseimet
Copy link
Contributor

uweseimet commented Nov 8, 2021

@jcs Sounds good. Depending on your results we can decide on the best approach, NOT_READY is most likely the best, because it reflects the Daynaport status and appears like a clean solution to me.

@uweseimet
Copy link
Contributor

uweseimet commented Nov 8, 2021

@jcs For completeness sake I checked what happens when an Atari accesses the Daynaport during the boot process. The Atari boots from the first device that provides a bootable root sector, and when booting the Atari tries to read the root sector with READ(6) regardless of the device type, just like your Mac.
Except for the fact that instead of 140 bytes (like in your log) only 100 bytes were returned (I guess the number of bytes is more or less random) your and my log are identical. The Atari appears to recover, though (i.e. it does not freeze), but the general scenario is the same.

jcs referenced this issue in jcs/RASCSI Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
jcs referenced this issue in jcs/RASCSI Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
@jcs
Copy link
Collaborator Author

jcs commented Nov 8, 2021

@uweseimet That approach did seem to work better and is a much smaller change.

It took me a while to figure out why the CDB control value test wasn't working in SCSIDaynaPort::Read. The cast of the cdb * data to a scsi_cmd_read_6_t struct is bogus because the data in cdb * is not packed raw SCSI data (each DWORD was manually copied into cmd before this function). If you print out each value of the command object after the cast, you'll see that the fields after operation_code are all zero. This seems to be the only driver and function that tries to put CDB data back into a SCSI command type, and it's only used to fetch two fields, so it might be easier just to avoid doing this altogether. I made a separate commit for that.

If either of these two changes are wanted, I can make separate pull requests for them.

@uweseimet
Copy link
Contributor

uweseimet commented Nov 8, 2021

@jcs I suggest to use the NOT_READY approach. This one is clean and straightforward. The device is not ready, and it tells the SCSI initiator so by using the error code reserved for such a case. With the CDB approach we would rely on undocumented (there is no official documentation for the Daynaport) behavior, which might have side effects
Can you please prepare a PR with the NOT_READY change?
Maybe you can also fix any issues with printing/handling the CDB values?

jcs referenced this issue in jcs/RASCSI Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
jcs referenced this issue in jcs/RASCSI Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
uweseimet referenced this issue Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
@jcs
Copy link
Collaborator Author

jcs commented Nov 8, 2021

Fixed via f2b5d86

@jcs jcs closed this as completed Nov 8, 2021
uweseimet referenced this issue Nov 8, 2021
All traffic from the DaynaPort will have a control value of 0xc0 or
0x80, so any commands that don't should be ignored.

This helps the Mac Plus which will try to READ(6) from the DaynaPort
device if it's attached at boot and then try to interpret the
ethernet packet as hard drive data and crash.

See issue akuker#419
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants