[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SCSI model detection fix (patch)
From: |
Hong H. Pham |
Subject: |
SCSI model detection fix (patch) |
Date: |
Sat, 17 Nov 2001 17:58:39 -0500 (EST) |
Hi Andrew,
Attached is a patch against libparted 1.5.5pre2 that fixes SCSI model
detection. The current code always return an "Unknown SCSI" for the
device model, due to improperly processing the structure returned from a
SCSI INQUIRY command.
Some minor fixes were made to the allocation of the device path; all
instances of the device paths are now dynamically allocated so that they
can all be safely freed upon invoking ped_device_destroy().
Cheers!
..Hong
diff -urN parted-1.5.5-pre2.old/libparted/linux.c
parted-1.5.5-pre2/libparted/linux.c
--- parted-1.5.5-pre2.old/libparted/linux.c Fri Nov 9 04:53:39 2001
+++ parted-1.5.5-pre2/libparted/linux.c Fri Nov 16 16:19:29 2001
@@ -372,6 +372,8 @@
return 0;
}
+#if 0
+// HHP
static char*
strip_name(char* n)
{
@@ -389,6 +391,22 @@
n[end] = 0;
return (strdup(n));
}
+#endif
+
+static char*
+strip_name(char* s)
+{
+ for (; *s; ++s) {
+ if ( (*s == ' ') ) {
+ if ( *(s+1) == '\0' || *(s+1) == ' ' ) {
+ *s = '\0';
+ break;
+ }
+ }
+ }
+ return s;
+}
+
static int
init_ide (PedDevice* dev)
@@ -398,6 +416,7 @@
int dev_major;
struct hd_driveid hdi;
PedExceptionOption ex_status;
+ char hdi_buf[41];
if (!_device_stat (dev, &dev_stat))
goto error;
@@ -420,10 +439,14 @@
case PED_EXCEPTION_UNHANDLED:
ped_exception_catch ();
case PED_EXCEPTION_IGNORE:
- dev->model = strdup(_("unknown"));
+ dev->model = strdup (_("Unknown IDE"));
}
} else {
- dev->model = strip_name (hdi.model);
+ /* hdi.model is not guaranteed to be NULL terminated */
+ memcpy (hdi_buf, hdi.model, 40);
+ hdi_buf[40] = '\0';
+ strip_name (hdi_buf);
+ dev->model = strdup (hdi_buf);
}
if (!_device_probe_geometry (dev))
@@ -441,58 +464,105 @@
static int
init_scsi (PedDevice* dev)
{
- LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
- unsigned char idlun [8];
- unsigned char buffer [128];
- unsigned char* cmd;
- struct hd_geometry geometry;
+ /* The following are defined by the SCSI-2 specification. */
+ typedef struct _scsi_inquiry_cmd
+ {
+ char op;
+ char lun; /* bits 5-7 denote the LUN */
+ char page_code;
+ char reserved;
+ char alloc_length;
+ char control;
+ } __attribute__((packed)) scsi_inquiry_cmd_t;
+
+ typedef struct _scsi_inquiry_data
+ {
+ char peripheral_info;
+ char device_info;
+ char version_info;
+ char _field1;
+ char additional_length;
+ char _reserved1;
+ char _reserved2;
+ char _field2;
+ char vendor_id[8];
+ char product_id[16];
+ char product_revision[4];
+ char vendor_specific[20];
+ char _reserved3[40];
+ } __attribute__((packed)) scsi_inquiry_data_t;
+
+ struct scsi_arg
+ {
+ unsigned int inlen;
+ unsigned int outlen;
+
+ union arg_data
+ {
+ scsi_inquiry_data_t out;
+ scsi_inquiry_cmd_t in;
+ } data;
+ } arg;
+
+ struct scsi_idlun
+ {
+ u_int32_t dev_id;
+ u_int32_t host_unique_id;
+ } idlun;
+
+ LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
+ char buf[256];
+ char *s;
if (!ped_device_open (dev))
- goto error;
+ return 0;
- memset (buffer, 0, 96);
+ if (ioctl (arch_specific->fd, SCSI_IOCTL_GET_IDLUN, &idlun) < 0) {
+ ped_exception_throw (PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_CANCEL,
+ _("Error initialising SCSI device "
+ "%s - %s"),
+ dev->path, strerror (errno));
+ ped_device_close (dev);
+ return 0;
+ }
- *((int *) buffer) = 0; /* length of input data */
- *(((int *) buffer) + 1) = 96; /* length of output buffer */
+ dev->host = idlun.host_unique_id;
+ dev->did = idlun.dev_id;
- cmd = (char *) (((int *) buffer) + 2);
+ memset (&arg, 0x00, sizeof(struct scsi_arg));
+ arg.inlen = 0;
+ arg.outlen = sizeof(scsi_inquiry_data_t);
+ arg.data.in.op = INQUIRY;
+ arg.data.in.lun = idlun.host_unique_id << 5;
+ arg.data.in.alloc_length = sizeof(scsi_inquiry_data_t);
+ arg.data.in.page_code = arg.data.in.reserved = \
+ arg.data.in.control = 0;
- cmd[0] = 0x12; /* INQUIRY */
- cmd[1] = 0x00; /* lun=0, evpd=0 */
- cmd[2] = 0x00; /* page code = 0 */
- cmd[3] = 0x00; /* (reserved) */
- cmd[4] = 96; /* allocation length */
- cmd[5] = 0x00; /* control */
-
- if (ioctl (arch_specific->fd, SCSI_IOCTL_SEND_COMMAND, buffer)) {
- buffer[40] = 0;
- dev->model = strip_name (buffer + 16);
+ if (ioctl (arch_specific->fd, SCSI_IOCTL_SEND_COMMAND, &arg) < 0) {
+ s = _("Unknown SCSI");
} else {
- dev->model = _("Unknown SCSI");
- }
+ memcpy (buf, arg.data.out.vendor_id, 8);
+ buf[8] = '\0';
+ s = strip_name (buf);
+ *s++ = ' ';
+
+ memcpy (s, arg.data.out.product_id, 16);
+ s[16] = '\0';
+ s = strip_name (s);
+ *s = '\0';
- if (ioctl (arch_specific->fd, SCSI_IOCTL_GET_IDLUN, idlun)) {
- ped_exception_throw (PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Error initialising SCSI device "
- "%s - %s"),
- dev->path, strerror (errno));
- goto error_close_dev;
+ s = buf;
}
+ dev->model = strdup (s);
- if (!_device_probe_geometry (dev))
- goto error_close_dev;
-
- dev->host = *((unsigned long *) (idlun + 4));
- dev->did = idlun [0];
+ if (!_device_probe_geometry (dev)) {
+ ped_device_close (dev);
+ return 0;
+ }
ped_device_close (dev);
return 1;
-
-error_close_dev:
- ped_device_close (dev);
-error:
- return 0;
}
static int
@@ -509,7 +579,7 @@
dev->sectors = 32;
dev->sector_size = 512;
dev->geom_known = 0;
- dev->model = "";
+ dev->model = strdup ("");
return 1;
}
@@ -558,7 +628,7 @@
dev->geom_known = 0;
}
- dev->model = model_name;
+ dev->model = strdup (model_name);
ped_device_close (dev);
return 1;
@@ -671,6 +741,7 @@
{
ped_free (dev->arch_specific);
ped_free (dev->path);
+ ped_free (dev->model);
ped_free (dev);
}
diff -urN parted-1.5.5-pre2.old/parted.spec parted-1.5.5-pre2/parted.spec
--- parted-1.5.5-pre2.old/parted.spec Sat Nov 10 16:54:06 2001
+++ parted-1.5.5-pre2/parted.spec Wed Dec 31 19:00:00 1969
@@ -1,78 +0,0 @@
-%define name parted
-%define ver 1.5.5-pre2
-%define rel 1
-%define prefix /usr
-%define sbindir /sbin
-%define mandir /usr/man
-%define aclocaldir /usr/share/aclocal
-
-
-Summary : flexible partitioning tool
-Name : %{name}
-Version : %{ver}
-Release : %{rel}
-Source : ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{ver}.tar.gz
-Buildroot : %{_tmppath}/%{name}-root
-Packager : Fabian Emmes <address@hidden>
-Copyright : GPL
-Group : Applications/System
-Requires : e2fsprogs, readline
-BuildPrereq : e2fsprogs-devel, readline-devel
-%description
-GNU Parted is a program that allows you to create, destroy,
-resize, move and copy hard disk partitions. This is useful for
-creating space for new operating systems, reorganising disk
-usage, and copying data to new hard disks.
-
-
-%package devel
-Summary : files required to compile software that uses libparted
-Group : Development/System
-Requires : e2fsprogs
-BuildPrereq : e2fsprogs-devel, readline-devel
-%description devel
-This package includes the header files and libraries needed to
-statically link software with libparted.
-
-
-%prep
-%setup
-
-%build
-if [ -n "$LINGUAS" ]; then unset LINGUAS; fi
-%configure --prefix=%{prefix} --sbindir=%{sbindir}
-make
-
-
-%install
-rm -rf "$RPM_BUILD_ROOT"
-make DESTDIR="$RPM_BUILD_ROOT" install
-strip "${RPM_BUILD_ROOT}%{sbindir}"/parted
-
-
-%clean
-rm -rf "$RPM_BUILD_ROOT"
-
-
-%files
-%defattr(-,root,root)
-%doc AUTHORS BUGS COPYING ChangeLog NEWS README THANKS TODO doc/COPYING.DOC
doc/API doc/USER doc/FAT
-%{prefix}/share/locale/*/*/*
-%{sbindir}/*
-%{mandir}/*/*
-%{prefix}/lib/*.so*
-
-
-%files devel
-%defattr(-,root,root)
-%{prefix}/include/*
-%{aclocaldir}/*
-%{prefix}/lib/*.a*
-%{prefix}/lib/*.la*
-
-%changelog
-* Mon Mar 13 2000 Fabian Emmes <address@hidden>
-- changed "unset LINGUAS" line
-- reintroduced %build section ;)
-- started changelog
-
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- SCSI model detection fix (patch),
Hong H. Pham <=