Getting "disk not ejected properly" in OSX

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Getting "disk not ejected properly" in OSX

Post by blmorris » Mon Sep 15, 2014 2:28 am

Today, after disabling disk sleep (sudo pmset -a disk sleep 0) I was able to keep a pyboard plugged in for several hours- opening, editing, saving files - without any hiccups. I could never do this before. While I will continue watching, I would tentatively say that the problem has been identified.

(There was one exception: I use Aquamacs, an emacs port for OSX, and kept getting the message that the disk could not be ejected because Aquamacs was using it. This was after all buffers referring to the pyboard drive were saved and closed; I had to close Aquamacs to get a clean eject. However I'm pretty sure this is an Aquamacs problem and not a Micro Python problem.)

My question now is whether anything can be done in Micro Python to fix this. I'm pretty sure that this problem doesn't pop up when using USB flash drives, and I would't what to tell mac users that the solution is to disable the mechanism that puts disks to sleep. Is it possible that Micro Python is doing something a little bit off here? Should I raise it on GitHub? There seems to be enough evidence at this point that this is a real issue.
robbie wrote:Maybe for SD cards disksleep tries to trigger something along these lines? Equally it could be just a coincidence.
For the most part I have only been using pyboards with the processor's internal flash, not SD cards, so I'm pretty sure that the problem is separate from any SD card issues.

jorjun
Posts: 4
Joined: Fri Sep 12, 2014 1:15 pm

Re: Getting "disk not ejected properly" in OSX

Post by jorjun » Thu Sep 18, 2014 6:12 am

The problem described is familiar to me, also. I am running the latest OS X beta. To successfully develop for the board, I found that I have to eject via finder, before three or so minutes or else it becomes impossible to eject and then I have to reset. Resetting the board after the freeze, then results in the message from finder: about volume not being ejected properly. Development is manageable, except sometimes corruption of main.py can happen, so you find yourself editing Mac filesystem python source as a backup & frequently copying this to the board - just in case another corruption occurs.

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Getting "disk not ejected properly" in OSX

Post by blmorris » Thu Sep 18, 2014 3:57 pm

jorjun wrote:The problem described is familiar to me, also. I am running the latest OS X beta. To successfully develop for the board, I found that I have to eject via finder, before three or so minutes or else it becomes impossible to eject and then I have to reset. Resetting the board after the freeze, then results in the message from finder: about volume not being ejected properly. Development is manageable, except sometimes corruption of main.py can happen, so you find yourself editing Mac filesystem python source as a backup & frequently copying this to the board - just in case another corruption occurs.
Thanks for reporting your experience with this. Can you try disabling disksleep and and let us know if it continues? It would be good to have further confirmation on another system.

Code: Select all

sudo pmset -a disksleep 0
I noticed that 'disksleep' was autocorrected to 'disk sleep' in my previous post, which of course is incorrect. ;)
You can also run

Code: Select all

sudo pmset -g
first to find your current setting for 'disksleep' so you can return to it after your test.
Thanks, Bryan

jorjun
Posts: 4
Joined: Fri Sep 12, 2014 1:15 pm

Re: Getting "disk not ejected properly" in OSX

Post by jorjun » Thu Sep 18, 2014 4:19 pm

Aha, thanks very much. Will do this. Thanks so much Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Getting "disk not ejected properly" in OSX

Post by dhylands » Sat Sep 20, 2014 2:12 am

Bryan sent me some traces a couple weeks ago, and I finally got a chance to look at them. I think I may have found the problem, and here's my analysis:

In capture 5, index 6291 (at 5:23:216.359) I see the following data being sent to the pyboard:

Code: Select all

55 53 42 43 31 00 00 00 00 00 00 00 00 00 06 1B 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
This is essentially a SCSI command wrapped up in a USB packet. The 06 is a length, and the 6 bytes after that is the actual SCSI command, which would be:

Code: Select all

1B 00 00 00 01 00
If you examine that (see page 221 of this document: http://www.seagate.com/staticfiles/supp ... 93068c.pdf) then we see that this is a START_STOP_UNIT command.
The non-zero data is byte 4, which has the START bit set. So the Mac is sending a START_STOP_UNIT with START set to the pyboard (essentially to say wakeup, I've got something coming).

Now if we go and look at the code, in the micropython/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c at the SCSI_StartStopUnit function (line 447) we see this:

Code: Select all

static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef  *pdev, uint8_t lun, uint8_t *params)
{
  USBD_MSC_BOT_HandleTypeDef  *hmsc = pdev->pClassData;  
  hmsc->bot_data_length = 0;

  // On Mac OS X, when the device is ejected a SCSI_START_STOP_UNIT command is sent.
  // params[1]==0 means stop, param[1]==1 seems to be something else (happens after the
  // device is plugged in and mounted for some time, probably a keep alive).
  // If we get a stop, we must really stop the device so that the Mac does not
  // automatically remount it.
  if (params[1] == 0) {
      ((USBD_StorageTypeDef *)pdev->pUserData)->StopUnit(lun);
  }

  return 0;
}
I looked at where this is called and params is basically a pointer to the SCSI command block, (the 0x1B bytes in the packet above), and it should be looking at the START bit, which is in params[4] not params[1].
params[1] is 0, so the code is incorrectly interpreting his as a STOP command instead of a START command. So it goes and shuts things down.

Back to the trace, Index 6224 is the response to the START_STOP_UNIT, and index 6229 is a READ (0x28) command, to which the pyboard doesn't respond (since it was just stopped). This causes the STALL in the trace.

The host tries a few more READS later on, which all STALL, and it eventually decides that things have gone bad and pops up an error.

So, if somebody could try editing that file https://github.com/micropython/micropyt ... csi.c#L457 and change the params[1] to a params[4] and see if that fixes things, that would be great.

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Getting "disk not ejected properly" in OSX

Post by blmorris » Sat Sep 20, 2014 2:40 am

Hi Dave - Thanks for looking so closely into this. While I don't know much about the low-level USB transactions you described, it certainly fits with the story that the Mac is sending some sort of sleep / wake command which is getting misinterpreted. Since I disabled the 'disksleep' parameter the problem hasn't recurred for me - not that this is a real solution, of course.
I should be able to test your fix, though probably not during the weekend, as I seem to have left all my uPy-capable hardware (pyboards and my own stuff) at work.
Will definitely try first thing on Monday if nobody gets to it before me.
-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Getting "disk not ejected properly" in OSX

Post by dhylands » Sat Sep 20, 2014 8:41 pm

Actually, a better thing to try would be:

Code: Select all

if ((param[4] & 1) == 0)

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Getting "disk not ejected properly" in OSX

Post by blmorris » Sun Sep 21, 2014 2:44 am

Hi Dave- It turns out that I did find my pyboard so I could try the test - unfortunately, "if ((params[4] & 1) == 0)" didn't fix the problem. I suspect that this is the right track, though, so I'll keep looking into it also now that I have a better idea what to look for. I don't have the Beagle with me so I can't do a trace, I just confirmed that we still get the "disk was not ejected properly" message.
-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Getting "disk not ejected properly" in OSX

Post by dhylands » Sun Sep 21, 2014 3:30 am

It could just be that we're hitting the next problem now.

Now that I know what to look for, I could also add some logging into the code to print out the SCSI messages received and then we wouldn't need the Beagle (unless its really obscure).

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Getting "disk not ejected properly" in OSX

Post by blmorris » Sun Sep 21, 2014 7:34 pm

Dave- I'll be happy to test any ideas or code you might suggest, and I'll keep looking into it myself as time allows. While I'm no expert in C (I learned the "equations and formulas for engineers" subset of C many years ago, which glossed over how to do anything interesting with pointers), I can probably write the code to do the simple stuff. Feel free to email me directly if you think of anything to try.

-Bryan

Post Reply