Index: uspace/drv/bus/usb/usbmast/inquiry.c
===================================================================
--- uspace/drv/bus/usb/usbmast/inquiry.c	(revision 8e1a819e63c991eb698215d0afabe2a2b5b1ce48)
+++ uspace/drv/bus/usb/usbmast/inquiry.c	(revision dcb74c0af02cb41ce55ef7d1413cdf60fdf07961)
@@ -62,17 +62,4 @@
 }
 
-/** Trim trailing spaces from a string (rewrite with string terminator).
- *
- * @param name String to be trimmed (in-out parameter).
- */
-static void trim_trailing_spaces(char *name)
-{
-	size_t len = str_length(name);
-	while ((len > 0) && isspace((int) name[len - 1])) {
-		name[len - 1] = 0;
-		len--;
-	}
-}
-
 /** Perform SCSI INQUIRY command on USB mass storage device.
  *
@@ -126,15 +113,12 @@
 	    SCSI_RMB_RMB, SCSI_RMB_RMB);
 
-	str_ncpy(inquiry_result->vendor, 1 + sizeof(inq_data.vendor),
-	    (const char *) &inq_data.vendor, sizeof(inq_data.vendor));
-	trim_trailing_spaces(inquiry_result->vendor);
+	spascii_to_str(inquiry_result->vendor, SCSI_INQ_VENDOR_STR_BUFSIZE,
+	    inq_data.vendor, sizeof(inq_data.vendor));
 
-	str_ncpy(inquiry_result->product, 1 + sizeof(inq_data.product),
-	    (const char *) &inq_data.product, sizeof(inq_data.product));
-	trim_trailing_spaces(inquiry_result->product);
+	spascii_to_str(inquiry_result->product, SCSI_INQ_PRODUCT_STR_BUFSIZE,
+	    inq_data.product, sizeof(inq_data.product));
 
-	str_ncpy(inquiry_result->revision, 1 + sizeof(inq_data.revision),
-	    (const char *) &inq_data.revision, sizeof(inq_data.revision));
-	trim_trailing_spaces(inquiry_result->revision);
+	spascii_to_str(inquiry_result->revision, SCSI_INQ_REVISION_STR_BUFSIZE,
+	    inq_data.revision, sizeof(inq_data.revision));
 
 	return EOK;
Index: uspace/drv/bus/usb/usbmast/mast.h
===================================================================
--- uspace/drv/bus/usb/usbmast/mast.h	(revision 8e1a819e63c991eb698215d0afabe2a2b5b1ce48)
+++ uspace/drv/bus/usb/usbmast/mast.h	(revision dcb74c0af02cb41ce55ef7d1413cdf60fdf07961)
@@ -37,4 +37,5 @@
 #define USB_USBMAST_MAST_H_
 
+#include <scsi/spc.h>
 #include <sys/types.h>
 #include <usb/usb.h>
@@ -52,9 +53,9 @@
 	bool removable;
 	/** Vendor ID string */
-	char vendor[9];
+	char vendor[SCSI_INQ_VENDOR_STR_BUFSIZE];
 	/** Product ID string */
-	char product[17];
+	char product[SCSI_INQ_PRODUCT_STR_BUFSIZE];
 	/** Revision string */
-	char revision[17];
+	char revision[SCSI_INQ_REVISION_STR_BUFSIZE];
 } usb_massstor_inquiry_result_t;
 
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 8e1a819e63c991eb698215d0afabe2a2b5b1ce48)
+++ uspace/lib/c/generic/str.c	(revision dcb74c0af02cb41ce55ef7d1413cdf60fdf07961)
@@ -544,4 +544,67 @@
 	
 	str_cpy(dest + dstr_size, size - dstr_size, src);
+}
+
+/** Convert space-padded ASCII to string.
+ *
+ * Common legacy text encoding in hardware is 7-bit ASCII fitted into
+ * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
+ * (ASCII 0x20). Convert space-padded ascii to string representation.
+ *
+ * If the text does not fit into the destination buffer, the function converts
+ * as many characters as possible and returns EOVERFLOW.
+ *
+ * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
+ * converted anyway and invalid characters are replaced with question marks
+ * (U_SPECIAL) and the function returns EIO.
+ *
+ * Regardless of return value upon return @a dest will always be well-formed.
+ *
+ * @param dest		Destination buffer
+ * @param size		Size of destination buffer
+ * @param src		Space-padded ASCII.
+ * @param n		Size of the source buffer in bytes.
+ *
+ * @return		EOK on success, EOVERFLOW if the text does not fit
+ *			destination buffer, EIO if the text contains
+ *			non-ASCII bytes.
+ */
+int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
+{
+	size_t sidx;
+	size_t didx;
+	size_t dlast;
+	uint8_t byte;
+	int rc;
+	int result;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+	result = EOK;
+
+	didx = 0;
+	dlast = 0;
+	for (sidx = 0; sidx < n; ++sidx) {
+		byte = src[sidx];
+		if (!ascii_check(byte)) {
+			byte = U_SPECIAL;
+			result = EIO;
+		}
+
+		rc = chr_encode(byte, dest, &didx, size - 1);
+		if (rc != EOK) {
+			assert(rc == EOVERFLOW);
+			dest[didx] = '\0';
+			return rc;
+		}
+
+		/* Remember dest index after last non-empty character */
+		if (byte != 0x20)
+			dlast = didx;
+	}
+
+	/* Terminate string after last non-empty character */
+	dest[dlast] = '\0';
+	return result;
 }
 
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 8e1a819e63c991eb698215d0afabe2a2b5b1ce48)
+++ uspace/lib/c/include/str.h	(revision dcb74c0af02cb41ce55ef7d1413cdf60fdf07961)
@@ -48,4 +48,10 @@
 #define STR_BOUNDS(length)  ((length) << 2)
 
+/**
+ * Maximum size of a buffer needed to a string converted from space-padded
+ * ASCII of size @a spa_size using spascii_to_str().
+ */
+#define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
+
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
 extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
@@ -73,4 +79,5 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
+extern int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 extern char *wstr_to_astr(const wchar_t *src);
Index: uspace/lib/scsi/include/scsi/spc.h
===================================================================
--- uspace/lib/scsi/include/scsi/spc.h	(revision 8e1a819e63c991eb698215d0afabe2a2b5b1ce48)
+++ uspace/lib/scsi/include/scsi/spc.h	(revision dcb74c0af02cb41ce55ef7d1413cdf60fdf07961)
@@ -38,4 +38,5 @@
 
 #include <stdint.h>
+#include <str.h>
 
 /** SCSI command codes defined in SCSI-SPC */
@@ -93,4 +94,20 @@
 } scsi_std_inquiry_data_t;
 
+/** Size of struct or union member. */
+#define SCSI_MEMBER_SIZE(type, member) \
+    (sizeof(((type *)0) -> member))
+
+/** Size of string buffer needed to hold converted inquiry vendor string */
+#define SCSI_INQ_VENDOR_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, vendor))
+
+/** Size of string buffer needed to hold converted inquiry product string */
+#define SCSI_INQ_PRODUCT_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, product))
+
+/** Size of string buffer needed to hold converted inquiry revision string */
+#define SCSI_INQ_REVISION_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, revision))
+
 /** Bits in scsi_std_inquiry_data_t.pqual_devtype */
 enum scsi_pqual_devtype_bits {
