bug-parted
[Top][All Lists]
Advanced

[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
-




reply via email to

[Prev in Thread] Current Thread [Next in Thread]