• Home
  • Help
  • Search
  • Login
  • Register
Pages: [1]
Author Topic: SATA hard drive spin down  (Read 3490 times)
jlinton
Newbie
*

Karma: 0
Posts: 12


View Profile
« on: December 14, 2009, 11:36:43 PM »

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.



Code:
/*
 * 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
Logged

MarkF
Full Member
***

Karma: 7
Posts: 144


View Profile
« Reply #1 on: December 15, 2009, 06:39:03 AM »

Cool.  Does the drive automatically spin back up when a request is made?
Logged

Mark

j0n3s
Newbie
*

Karma: 2
Posts: 13


View Profile
« Reply #2 on: December 15, 2009, 07:19:47 AM »

Nice.

But what is advantage over hdparm? Tongue
Logged

jlinton
Newbie
*

Karma: 0
Posts: 12


View Profile
« Reply #3 on: December 15, 2009, 09:14:25 AM »

MarkF: Yes, the drives spin back up. This is simply an ATA STANDBY IMMEDIATE. This spins them down, but leaves the controller active. The controller will automatically spin them back up for the next read/write.

Jon3s, In my case hdparm simply doesn't work, it fails because the marvell driver isn't integrated well with the kernel libata interfaces. This is what happens when I send hdparm -y.

/sbin/hdparm -y /dev/sda

/dev/sda:
 issuing standby command
SG_IO: bad/missing ATA_16 sense data::  72 05 20 00 00 00 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SG_IO: bad/missing ATA_16 sense data::  72 05 20 00 00 00 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 HDIO_DRIVE_CMD(standby) failed: Input/output error


I'm going to upgrade to a newer kernel, and if it still fails probably patch the driver. I suspect that hdparm and sg_start should be working in more recent kernels.

Logged

Pages: [1]
Print
Jump to: