hal/drive_id Makefile.am, NONE, 1.1 ata.c, NONE, 1.1 ata.h, NONE, 1.1 drive_id.c, NONE, 1.1 drive_id.h, NONE, 1.1 logging.h, NONE, 1.1 scsi.c, NONE, 1.1 scsi.h, NONE, 1.1 util.c, NONE, 1.1 util.h, NONE, 1.1

David Zeuthen david at freedesktop.org
Mon Feb 7 13:24:18 PST 2005


Update of /cvs/hal/hal/drive_id
In directory gabe:/tmp/cvs-serv25257/drive_id

Added Files:
	Makefile.am ata.c ata.h drive_id.c drive_id.h logging.h scsi.c 
	scsi.h util.c util.h 
Log Message:
2005-02-07  David Zeuthen  <davidz at redhat.com>

	* drive_id/*: Add new drive_id library from Kay

	* volume_id/*: Add new volume_id library from Kay

	* Makefile.am: Add drive_id and volume_id to SUBDIRS

	* configure.in: Add drive_id and volume_id to AC_OUTPUT



--- NEW FILE: Makefile.am ---

noinst_LTLIBRARIES = libdrive_id.la

libdrive_id_la_SOURCES =				\
	ata.h			ata.c			\
	scsi.h			scsi.c			\
	logging.h					\
	util.h			util.c			\
	drive_id.h		drive_id.c


--- NEW FILE: ata.c ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 * 	Try to get vendor, model, serial number, firmware version
 *	of ATA or SCSI devices.
 *	
 *	Note:	Native interface access is needed. There is no way to get
 *		these kind from a device behind a USB adapter. A good
 *		bridge reads these values from the device and provides them
 *		as USB config strings.
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <scsi/sg.h>
#include <linux/hdreg.h>
#include <asm/types.h>

#include "drive_id.h"
#include "logging.h"
#include "util.h"
#include "ata.h"

int drive_id_probe_ata(struct drive_id *id)
{
	struct hd_driveid ata_id;

	if (ioctl(id->fd, HDIO_GET_IDENTITY, &ata_id) != 0)
		return -1;

	set_str(id->model, ata_id.model, 40);
	set_str(id->serial, ata_id.serial_no, 20);
	set_str(id->firmware, ata_id.fw_rev, 8);

	return 0;
}

--- NEW FILE: ata.h ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _DRIVE_ID_ATA_
#define _DRIVE_ID_ATA_

extern int drive_id_probe_ata(struct drive_id *id);

#endif

--- NEW FILE: drive_id.c ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 * 	Get vendor, model, serial number, firmware version of
 * 	ATA or SCSI devices.
 *	
 *	Note:	Native interface access is needed. There is no way to get
 *		these kind from a device behind a USB adapter. A good
 *		bridge reads these values from the device and provides them
 *		as USB config strings.
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <scsi/sg.h>
#include <linux/hdreg.h>
#include <asm/types.h>

#include "drive_id.h"
#include "logging.h"
#include "util.h"

#include "scsi.h"
#include "ata.h"

int drive_id_probe_all(struct drive_id *id)
{
	if (id == NULL)
		return -1;

	if (drive_id_probe_ata(id) == 0)
		goto exit;
	if (drive_id_probe_scsi(id) == 0)
		goto exit;

	return -1;
	
exit:
	return 0;
}

/* open drive by already open file descriptor */
struct drive_id *drive_id_open_fd(int fd)
{
	struct drive_id *id;

	id = malloc(sizeof(struct drive_id));
	if (id == NULL)
		return NULL;
	memset(id, 0x00, sizeof(struct drive_id));

	id->fd = fd;

	return id;
}

/* open drive by device node */
struct drive_id *drive_id_open_node(const char *path)
{
	struct drive_id *id;
	int fd;

	fd = open(path, O_RDONLY | O_NONBLOCK);
	if (fd < 0) {
		dbg("unable to open '%s'", path);
		return NULL;
	}

	id = drive_id_open_fd(fd);
	if (id == NULL)
		return NULL;

	/* close fd on device close */
	id->fd_close = 1;

	return id;
}

/* open drive by major/minor */
struct drive_id *drive_id_open_dev_t(dev_t devt)
{
	struct drive_id *id;
	__u8 tmp_node[DRIVE_ID_PATH_MAX];

	snprintf(tmp_node, DRIVE_ID_PATH_MAX,
		 "/dev/.drive_id-%u-%u-%u", getpid(), major(devt), minor(devt));
	tmp_node[DRIVE_ID_PATH_MAX] = '\0';

	/* create tempory node to open the block device */
	unlink(tmp_node);
	if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0)
		return NULL;

	id = drive_id_open_node(tmp_node);

	unlink(tmp_node);

	return id;
}

/* free allocated drive info */
void drive_id_close(struct drive_id *id)
{
	if (id == NULL)
		return;

	if (id->fd_close != 0)
		close(id->fd);

	free(id);
}

--- NEW FILE: drive_id.h ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _DRIVE_ID_H_
#define _DRIVE_ID_H_

#define DRIVE_ID_VERSION		4

#define DRIVE_ID_VENDOR_SIZE		8
#define DRIVE_ID_MODEL_SIZE		40
#define DRIVE_ID_SERIAL_SIZE		20
#define DRIVE_ID_FW_SIZE		9
#define DRIVE_ID_REV_SIZE		12
#define DRIVE_ID_PATH_MAX		256

struct drive_id {
	char *type;
	unsigned char	vendor[DRIVE_ID_VENDOR_SIZE+1];
	unsigned char	model[DRIVE_ID_MODEL_SIZE+1];
	unsigned char	serial[DRIVE_ID_SERIAL_SIZE+1];
	unsigned char	firmware[DRIVE_ID_FW_SIZE+1];
	unsigned char	revision[DRIVE_ID_REV_SIZE+1];
	int		fd;
	int		fd_close;
};

/* open drive by already open file descriptor */
extern struct drive_id *drive_id_open_fd(int fd);

/* open drive by device node */
extern struct drive_id *drive_id_open_node(const char *path);

/* open drive by major/minor */
extern struct drive_id *drive_id_open_dev_t(dev_t devt);

/* probe drive for model/serial number */
extern int drive_id_probe_all(struct drive_id *id);

/* free allocated device info */
extern void drive_id_close(struct drive_id *id);

#endif /* _DRIVE_ID_H_ */

--- NEW FILE: logging.h ---
/*
 * drive_id_logging - this file is used to map the dbg() function
 *                     to the user's logging facility
 *
 */

#ifndef _DRIVE_ID_LOGGING_H_
#define _DRIVE_ID_LOGGING_H_

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef DEBUG
#define dbg(format, arg...)						\
	do {								\
		printf("%s: " format "\n", __FUNCTION__ , ## arg);	\
	} while (0)
#else
#define dbg(format, arg...)	do {} while (0)
#endif

#endif /* _DRIVE_ID_LOGGING_H_ */

--- NEW FILE: scsi.c ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 * 	Try to get vendor, model, serial number, firmware version
 *	of ATA or SCSI devices.
 *	
 *	Note:	Native interface access is needed. There is no way to get
 *		these kind from a device behind a USB adapter. A good
 *		bridge reads these values from the device and provides them
 *		as USB config strings.
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <scsi/sg.h>
#include <linux/hdreg.h>
#include <asm/types.h>

#include "drive_id.h"
#include "logging.h"
#include "util.h"
#include "scsi.h"


#define INQUIRY_CMD_LEN		6
#define SENSE_BUF_LEN		32
#define INQUIRY			0x12
#define TIMEOUT			3000
static int scsi_inq(int fd,
		    unsigned char evpd, unsigned char page,
		    unsigned char *buf, int buf_len)
{
	unsigned char cmd[INQUIRY_CMD_LEN];
	unsigned char sense[SENSE_BUF_LEN];
	struct sg_io_hdr io_hdr;
	int rc;

	cmd[0] = INQUIRY;
	cmd[1] = evpd;
	cmd[2] = page;
	cmd[3] = 0;
	cmd[4] = buf_len;
	cmd[5] = 0;

	memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
	io_hdr.interface_id = 'S';
	io_hdr.cmdp = cmd;
	io_hdr.cmd_len = sizeof(cmd);
	io_hdr.dxferp = buf;
	io_hdr.dxfer_len = buf_len;
	io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
	io_hdr.sbp = sense;
	io_hdr.mx_sb_len = sizeof(sense);
	io_hdr.timeout = TIMEOUT;

	rc = ioctl(fd, SG_IO, &io_hdr);
	if (rc != 0) {
		dbg("ioctl failed");
		return -1;
	}

	if (io_hdr.status != 0 ||
	    io_hdr.msg_status != 0 ||
	    io_hdr.host_status != 0 ||
	    io_hdr.driver_status != 0) {
		dbg("scsi status error");
		return -1;
	}

	if (buf[1] != page) {
		dbg("asked for page 0x%x, got page 0x%x", page, buf[1]);
		return -1;
	}

	return 0;
}

#define BUFFER_SIZE		256
int drive_id_probe_scsi(struct drive_id *id)
{
	unsigned char buf[BUFFER_SIZE];
	int len;
	int rc;

	/* get vendor product */
	memset(buf, 0, BUFFER_SIZE);
	rc = scsi_inq(id->fd, 0, 0x00, buf, 255);
	if (rc != 0) {
		dbg("inquiry page 0x00 failed");
		return -1;
	}

	set_str(id->vendor, &buf[8], 8);
	set_str(id->model, &buf[16], 16);
	set_str(id->revision, &buf[32], 12);

	/* get serial number from page 0x80 */
	memset(buf, 0, BUFFER_SIZE);
	rc = scsi_inq(id->fd, 1, 0x80, buf, 255);
	if (rc != 0) {
		dbg("inquiry page 0x80 failed");
		return -1;
	}
	len = buf[3];
	dbg("page 0x80 serial number length %i", len);
	if (len > DRIVE_ID_SERIAL_SIZE)
		len = DRIVE_ID_SERIAL_SIZE;
	set_str(id->serial, &buf[4], len);

	return 0;
}

--- NEW FILE: scsi.h ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _DRIVE_ID_SCSI_
#define _DRIVE_ID_SCSI_

extern int drive_id_probe_scsi(struct drive_id *id);

#endif

--- NEW FILE: util.c ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <asm/types.h>

#include "drive_id.h"
#include "logging.h"
#include "util.h"

void set_str(char *to, const unsigned char *from, int count)
{
	int first;
	int last;

	/* remove leading whitespace */
	for (first = 0; isspace(from[first]) && (first < count); first++);

	memcpy(to, &from[first], count - first);

	/* remove trailing whitespace */
	last = strnlen(to, count);
	while (last--) {
		if (! isspace(to[last]))
			break;
	}
	to[last+1] = '\0';
}


--- NEW FILE: util.h ---
/*
 * drive_id - reads drive model and serial number
 *
 * Copyright (C) 2005 Kay Sievers <kay.sievers at vrfy.org>
 *
 *	This library is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU Lesser General Public
 *	License as published by the Free Software Foundation; either
 *	version 2.1 of the License, or (at your option) any later version.
 *
 *	This library is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *	Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public
 *	License along with this library; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef _DRIVE_ID_UTIL_
#define _DRIVE_ID_UTIL_

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

extern void set_str(char *to, const unsigned char *from, int count);

#endif /* _DRIVE_ID_UTIL_ */





More information about the hal-commit mailing list