For spindown control, sg_start and hdparm don't appear to work with the default 2.6.22 kernel. To work around this, I've written some code using the old SCSI_IOCTL_SEND_COMMAND ioctl. This is the same ioctl smartctl uses with the -D marvell option. A quick look at the mvSata drive shows that it supports some other commands as "vendor specific". Including the ability to spin down a SATA drive.
/*
* spindown.cpp
*
* spins down hard drives attached to the marvell sata controller on a kirkwood
*
* Copyright (c) 2009 Jeremy Linton
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*/
#include <stddef.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int marvell_command_interface(int device)
{
typedef struct
{
int inlen;
int outlen;
char cmd[540];
} mvsata_scsi_cmd;
mvsata_scsi_cmd stop_command;
unsigned char *buff = (unsigned char *)&stop_command.cmd[6];
memset(&stop_command, 0, sizeof(stop_command));
stop_command.inlen = 540;
stop_command.outlen = 540;
stop_command.cmd[0] = 0xC; //Vendor-specific code
stop_command.cmd[4] = 6; //command length
buff[0]=0xE0; //ATA_COMMAND_STANDBY_IMMEDIATE;
if (ioctl(device, SCSI_IOCTL_SEND_COMMAND, (void *)&stop_command))
{
printf("failed to send ioctl\n");
return -1;
}
return 0;
}
int main(int argc,char *argv[])
{
if (argc!=2)
{
printf("Use like %s /dev/sd[x]\n",argv[0]);
}
else
{
int fd=open(argv[1],O_RDWR);
if (fd!=-1)
{
if (marvell_command_interface(fd)==0)
{
printf("Successfully spun down %s\n",argv[1]);
}
close(fd);
}
else
{
printf("Failed to open %s\n",argv[1]);
}
}
return 0;
}
So given this utility you can spin down a drive like ./spindown /dev/sda