From: Douglas Gilbert <dougg@torque.net>
To: Jeff Garzik <jgarzik@pobox.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH RFC] use struct scsi_lun in generic code
Date: Sun, 23 Oct 2005 15:22:22 +1000 [thread overview]
Message-ID: <435B1E0E.8060409@torque.net> (raw)
In-Reply-To: <20051023043301.GA22615@havoc.gtf.org>
[-- Attachment #1: Type: text/plain, Size: 1383 bytes --]
_rbuf_getJeff Garzik wrote:
> A further experiment: once dev_printk() has been used to eliminate
> direct references to HCIL address (see previous patch), we can see what
> happens when we update the core to use struct scsi_lun.
>
> DO NOT APPLY.
>
> Depends on previous "kill scsi_device::{channel,id} in generic code"
> patch.
>
> Changes:
>
> * replace 'unsigned int lun' with 'struct scsi_lun lun' in struct scsi_device
>
> * change various function args to receive 'const struct scsi_lun *'
> rather than unsigned int.
>
> * export scsilun_to_int()
>
> * create scsilun_to_str() helper
>
> * create scsilun_eq() helper
>
> * update all references to scsi_device::lun, as caught by the compiler.
>
> Again, generic code was 100% converted, driver code 0% converted.
>
> * int_to_scsilun() is used to convert SCSI-2 luns, and luns passed
> from userspace as integers, to struct scsi_lun.
>
> * shost->max_lun check moved into scsi_scan_host_selected() callers
Jeff,
With 8 byte luns, max_lun is legacy. I found it a nuisance
when I played with wluns (well known lus). Looks like
you may be coping with that.
If you want to decode SAM-4 luns, perhaps for verbose
error purposes, feel free to borrow code from the
attached sg_luns (which is slightly more up to date
than the one found in sg3_utils version 1.17).
Back to libata's MODE SELECT ...
Doug Gilbert
[-- Attachment #2: sg_luns.c --]
[-- Type: text/x-csrc, Size: 11679 bytes --]
/*
* Copyright (c) 2004 Douglas Gilbert.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sg_include.h"
#include "sg_lib.h"
#include "sg_cmds.h"
/* A utility program for the Linux OS SCSI subsystem.
*
*
* This program issues the SCSI command REPORT LUNS to the given SCSI device.
*/
static char * version_str = "1.04 20051013";
#define REPORT_LUNS_BUFF_LEN 1024
#define ME "sg_luns: "
static struct option long_options[] = {
{"decode", 0, 0, 'd'},
{"help", 0, 0, 'h'},
{"select", 1, 0, 's'},
{"verbose", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{0, 0, 0, 0},
};
static void usage()
{
fprintf(stderr, "Usage: "
"sg_luns [--decode] [--help] [--select=<n>] [--verbose] "
"[--version]\n"
" <scsi_device>\n"
" where: --decode|-d decode all luns into parts\n"
" --help|-h print out usage message\n"
" --select=<n>|-s <n> select report <n> (def: 0)\n"
" 0 -> luns apart from 'well "
"known' lus\n"
" 1 -> only 'well known' "
"logical unit numbers\n"
" 2 -> all luns\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
"Performs a REPORT LUNS SCSI command\n"
);
}
/* Decoded according to SAM-4 rev 3 (plus 05-376r2). Note that one
* draft: BCC rev 0, defines its own "bridge addressing method" in
* place of the SAM-3 "logical addressing method". */
static void decode_lun(const char * leadin, unsigned char * lunp)
{
int k, j, x, a_method, bus_id, target, lun, len, e_a_method, next_level;
unsigned char not_spec[8] = {0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff};
char l_leadin[128];
unsigned long long ull;
if (0 == memcmp(lunp, not_spec, sizeof(not_spec))) {
printf("%sLogical unit not specified\n", leadin);
return;
}
memset(l_leadin, 0, sizeof(l_leadin));
for (k = 0; k < 4; ++k, lunp += 2) {
next_level = 0;
strncpy(l_leadin, leadin, sizeof(l_leadin) - 3);
if (k > 0) {
printf("%s>>%s level addressing:\n", l_leadin,
((1 == k) ? "Second" : ((2 == k) ? "Third" : "Fourth")));
strcat(l_leadin, " ");
}
a_method = (lunp[0] >> 6) & 0x3;
switch (a_method) {
case 0: /* peripheral device addressing method */
bus_id = lunp[0] & 0x3f;
if (0 == bus_id)
printf("%sPeripheral device addressing: lun=%d\n",
l_leadin, lunp[1]);
else {
printf("%sPeripheral device addressing: bus_id=%d, "
"target=%d\n", l_leadin, bus_id, lunp[1]);
next_level = 1;
}
break;
case 1: /* flat space addressing method */
lun = ((lunp[0] & 0x3f) << 8) + lunp[1];
printf("%sFlat space addressing: lun=%d\n", l_leadin, lun);
break;
case 2: /* logical unit addressing method */
target = (lunp[0] & 0x3f);
bus_id = (lunp[1] >> 5) & 0x7;
lun = lunp[1] & 0x1f;
printf("%sLogical unit addressing: bus_id=%d, target=%d, "
"lun=%d\n", l_leadin, bus_id, target, lun);
break;
case 3: /* extended logical unit addressing method */
len = (lunp[0] & 0x30) >> 4;
e_a_method = lunp[0] & 0xf;
x = lunp[1];
if ((0 == len) && (1 == e_a_method)) {
switch (x) {
case 1:
printf("%sREPORT LUNS well known logical unit\n",
l_leadin);
break;
case 2:
printf("%sACCESS CONTROLS well known logical unit\n",
l_leadin);
break;
case 3:
printf("%sTARGET LOG PAGES well known logical unit\n",
l_leadin);
break;
default:
printf("%swell known logical unit %d\n", l_leadin, x);
break;
}
} else if ((1 == len) && (2 == e_a_method)) {
x = (lunp[1] << 16) + (lunp[2] << 8) + lunp[3];
printf("%sExtended flat space logical unit addressing: "
"value=0x%x\n", l_leadin, x);
} else if ((3 == len) && (0xf == e_a_method))
printf("%sLogical unit _not_ specified addressing\n",
l_leadin);
else {
if (len < 2) {
if (1 == len)
x = (lunp[1] << 16) + (lunp[2] << 8) + lunp[3];
printf("%sExtended logical unit addressing: length=%d, "
"e.a. method=%d, value=0x%x\n", l_leadin, len,
e_a_method, x);
} else {
ull = 0;
x = (2 == len) ? 5 : 7;
for (j = 0; j < x; ++j) {
if (j > 0)
ull <<= 8;
ull |= lunp[1 + j];
}
printf("%sExtended logical unit addressing: length=%d, "
"e. a. method=%d, value=0x%llx\n", l_leadin, len,
e_a_method, ull);
}
}
break;
default:
printf("%s<<decode_lun: faulty logic>>\n", l_leadin);
break;
}
if (next_level)
continue;
if ((2 == a_method) && (k < 3) && (lunp[2] || lunp[3]))
printf("%s<<unexpected data at next level, continue>>\n",
l_leadin);
break;
}
}
int main(int argc, char * argv[])
{
int sg_fd, k, m, off, res, c, list_len, luns, trunc;
unsigned char reportLunsBuff[REPORT_LUNS_BUFF_LEN];
int decode = 0;
int select_rep = 0;
int verbose = 0;
char device_name[256];
int ret = 1;
memset(device_name, 0, sizeof device_name);
while (1) {
int option_index = 0;
c = getopt_long(argc, argv, "dhs:vV", long_options,
&option_index);
if (c == -1)
break;
switch (c) {
case 'd':
decode = 1;
break;
case 'h':
case '?':
usage();
return 0;
case 's':
if ((1 != sscanf(optarg, "%d", &select_rep)) ||
(select_rep < 0) || (select_rep > 255)) {
fprintf(stderr, "bad argument to '--select'\n");
return 1;
}
break;
case 'v':
++verbose;
break;
case 'V':
fprintf(stderr, ME "version: %s\n", version_str);
return 0;
default:
fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
usage();
return 1;
}
}
if (optind < argc) {
if ('\0' == device_name[0]) {
strncpy(device_name, argv[optind], sizeof(device_name) - 1);
device_name[sizeof(device_name) - 1] = '\0';
++optind;
}
if (optind < argc) {
for (; optind < argc; ++optind)
fprintf(stderr, "Unexpected extra argument: %s\n",
argv[optind]);
usage();
return 1;
}
}
if (0 == device_name[0]) {
fprintf(stderr, "missing device name!\n");
usage();
return 1;
}
sg_fd = open(device_name, O_RDWR | O_NONBLOCK);
if (sg_fd < 0) {
fprintf(stderr, ME "open error: %s: ", device_name);
perror("");
return 1;
}
memset(reportLunsBuff, 0x0, sizeof(reportLunsBuff));
trunc = 0;
res = sg_ll_report_luns(sg_fd, select_rep, reportLunsBuff,
sizeof(reportLunsBuff), 1, verbose);
if (0 == res) {
list_len = (reportLunsBuff[0] << 24) + (reportLunsBuff[1] << 16) +
(reportLunsBuff[2] << 8) + reportLunsBuff[3];
luns = (list_len / 8);
printf("Lun list length = %d which imples %d lun entr%s\n",
list_len, luns, ((1 == luns) ? "y" : "ies"));
if ((list_len + 8) > (int)sizeof(reportLunsBuff)) {
luns = ((sizeof(reportLunsBuff) - 8) / 8);
trunc = 1;
printf(" <<too many luns for internal buffer, will show %d "
"luns>>\n", luns);
}
if (verbose) {
fprintf(stderr, "\nOutput response in hex\n");
dStrHex((const char *)reportLunsBuff,
(trunc ? (int)sizeof(reportLunsBuff) : list_len + 8), 1);
}
for (k = 0, off = 8; k < luns; ++k) {
if (0 == k)
printf("Report luns [select_report=%d]:\n", select_rep);
printf(" ");
for (m = 0; m < 8; ++m, ++off)
printf("%02x", reportLunsBuff[off]);
printf("\n");
if (decode)
decode_lun(" ", reportLunsBuff + off - 8);
}
ret = 0;
} else if (SG_LIB_CAT_INVALID_OP == res)
fprintf(stderr, "Report Luns command not supported (support "
"mandatory in SPC-3)\n");
else if (SG_LIB_CAT_ILLEGAL_REQ == res)
fprintf(stderr, "Report Luns command has bad fields in cdb\n");
else {
fprintf(stderr, "Report Luns command failed\n");
if (0 == verbose)
fprintf(stderr, " try '-v' option for more information\n");
}
res = close(sg_fd);
if (res < 0) {
perror(ME "close error");
return 1;
}
return ret;
}
next prev parent reply other threads:[~2005-10-23 5:21 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-10-23 4:33 [PATCH RFC] use struct scsi_lun in generic code Jeff Garzik
2005-10-23 4:49 ` [PATCH RFC] more struct scsi_lun Jeff Garzik
2005-10-23 9:47 ` Stefan Richter
2005-10-23 13:14 ` Stefan Richter
2005-10-23 16:49 ` Jeff Garzik
2005-10-24 16:27 ` Luben Tuikov
2005-10-24 20:03 ` Stefan Richter
2005-10-24 20:10 ` Luben Tuikov
2005-10-24 20:28 ` Mark Rustad
2005-10-24 22:27 ` Douglas Gilbert
2005-10-23 5:20 ` [PATCH RFC] use struct scsi_lun in generic code Jeff Garzik
2005-10-23 5:22 ` Douglas Gilbert [this message]
2005-10-23 7:01 ` Jeff Garzik
2005-10-24 14:55 ` Luben Tuikov
2005-10-23 7:00 ` [PATCH RFC] yet more struct scsi_lun Jeff Garzik
2005-10-23 10:48 ` Douglas Gilbert
2005-10-23 11:53 ` Arjan van de Ven
2005-10-23 14:27 ` max_sectors [was Re: [PATCH RFC] yet more struct scsi_lun] Douglas Gilbert
2005-10-23 14:42 ` Arjan van de Ven
2005-10-23 16:44 ` [PATCH RFC] yet more struct scsi_lun Jeff Garzik
2005-10-23 16:43 ` Jeff Garzik
2005-10-23 18:53 ` Kai Makisara
2005-10-24 7:59 ` Jens Axboe
2005-10-28 17:24 ` Mike Christie
2005-10-31 10:24 ` Jens Axboe
2005-11-04 2:23 ` Mike Christie
2005-11-04 2:25 ` Mike Christie
2005-11-04 7:37 ` Jens Axboe
2005-11-04 17:27 ` Mike Christie
2005-10-23 7:16 ` [PATCH RFC] even " Jeff Garzik
2005-10-24 15:27 ` [PATCH RFC] use struct scsi_lun in generic code Patrick Mansfield
2005-10-24 22:40 ` Douglas Gilbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=435B1E0E.8060409@torque.net \
--to=dougg@torque.net \
--cc=jgarzik@pobox.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).