wiki:DeveloperHowToMigrate

Version 1 (modified by Gabriele Pohl, 15 years ago) ( diff )

Insert content from old wiki

Migrate old os_youros.cpp to new class interface

Christian Franke wrote this quick outline how a migration works, which he already tested with os_linux.cpp.

Step 1: Move adapter classes into os_youros.cpp

  • Append adapter classes to old module:
    $ cat dev_legacy.cpp >> os_youros.cpp
    [[code]]
    - Re-configure, this should now detect new interface:
    [[code format="bash"]]
    $ ./configure
    ...
    checking whether os_youros.cpp uses new interface... yes
    
  • This should compile and work!
  • Move #includes to top, remove duplicates.
  • Remove all dummy functions for controllers not supported on your os (marvell_command_interface, ...).
  • Remove corresponding classes (e.g legacy_marvell_device, ...).
  • Remove corresponding section from legacy_smart_interface::get_custom_smart_device(). If nothing left, remove this function.
  • Rename remaining classes 'legacy_*' to 'youros_*'. Rename namespace 'os' to 'os_youros'.
  • This should compile and work!

Step 2: Merge old functions into class member functions

Old:

int deviceopen(const char *pathname, char *type)
{
  ...
  int fd = open(pathname, ...);
  ...
  return fd;
}

bool youros_smart_device::open()
{
  m_fd = ::deviceopen(get_dev_name(), (char*)m_mode);
  if (m_fd < 0) {
    set_err(errno);
    return false;
  }
  return true;
}

New:

bool youros_smart_device::open()
{
  ...
  m_fd = open(get_dev_name(), ...);
  if (m_fd < 0) {
    set_err(errno);
    return false;
  }
  return true;
}

Old:

int ata_command_interface(int fd, smart_command_set command, int select, char *data)
{
  ...
  if (ioctl(fd, ...))
    return -1;
  ...
  return 0;
}

int youros_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
{
  return ::ata_command_interface(get_fd(), command, select, data);
}

New:

int youros_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
{
  ...
  if (ioctl(get_fd(), ...))
    return -1;
  ...
  return 0;
}

Step 3: Convert SMART-only to full fledged ATA pass through

  • Change base class of 'youros_ata_device' from 'ata_device_with_command_set' to 'ata_device'.
  • Change 'youros_ata_device::ata_command_interface()' to 'youros_ata_device::ata_pass_through()'.
  • Add parameter check using ata_cmd_is_ok(in, 'supported features')
  • Remove 'switch (command) {....}', set ioctl input struct directly from input registers e.g. 'in.in_regs.*'.
  • Remove special handling for SMART STATUS, return result registers in 'out.out_regs' if requested by 'in.out_needed.is_set()'.
  • Adjust returns:
    Replace 'return 0;' by 'return true;'.
    Replace 'errno = ERR; return -1;' by 'return set_err(ERR, "optional message", ...)'.
    
  • Optional add 48bit ATA pass through support:
    If 'in.in_regs.is_48bit_cmd()' is set, 
    pass low (in.in_regs.lba_mid) and 
    high (in.in_regs.prev.lba_mid) byte of each register to ioctl.
    

Later

  • Rework device scanning.
  • Add/Rework auto-detection (function autodetect_open()).
  • remove os_youros.h, each module does only export smart_interface::init().

Example for Steps 1+2:

​http://smartmontools.cvs.sourceforge.net/viewvc/smartmontools/sm5/os_linux.cpp?r1=1.116&r2=1.117

Example for Step 3 (3ware only):

​http://smartmontools.cvs.sourceforge.net/viewvc/smartmontools/sm5/os_linux.cpp?r1=1.117&r2=1.118

Note: See TracWiki for help on using the wiki.