2003-05-30 12:49:33

by Jens Axboe

[permalink] [raw]
Subject: [PATCH] SG_IO readcd and various bugs

Hi,

Below patch should make readcd (and others) behave, please test.

===== drivers/block/ioctl.c 1.54 vs edited =====
--- 1.54/drivers/block/ioctl.c Sat Apr 26 00:16:28 2003
+++ edited/drivers/block/ioctl.c Fri May 30 10:25:55 2003
@@ -207,11 +207,8 @@
set_device_ro(bdev, n);
return 0;
default:
- if (disk->fops->ioctl) {
- ret = disk->fops->ioctl(inode, file, cmd, arg);
- if (ret != -EINVAL)
- return ret;
- }
+ if (disk->fops->ioctl)
+ return disk->fops->ioctl(inode, file, cmd, arg);
}
return -ENOTTY;
}
===== drivers/block/scsi_ioctl.c 1.27 vs edited =====
--- 1.27/drivers/block/scsi_ioctl.c Sat May 17 12:05:21 2003
+++ edited/drivers/block/scsi_ioctl.c Fri May 30 15:00:08 2003
@@ -68,7 +68,6 @@

rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
- drive_stat_acct(rq, rq->nr_sectors, 1);
elv_add_request(q, rq, 1, 1);
generic_unplug_device(q);
wait_for_completion(&wait);
@@ -99,7 +98,7 @@

static int sg_get_timeout(request_queue_t *q)
{
- return q->sg_timeout;
+ return q->sg_timeout / (HZ / USER_HZ);
}

static int sg_set_timeout(request_queue_t *q, int *p)
@@ -107,7 +106,7 @@
int timeout, err = get_user(timeout, p);

if (!err)
- q->sg_timeout = timeout;
+ q->sg_timeout = timeout * (HZ / USER_HZ);

return err;
}
@@ -121,10 +120,14 @@
{
int size, err = get_user(size, p);

- if (!err)
- q->sg_reserved_size = size;
+ if (err)
+ return err;

- return err;
+ if (size > (q->max_sectors << 9))
+ return -EINVAL;
+
+ q->sg_reserved_size = size;
+ return 0;
}

/*
@@ -139,16 +142,14 @@
static int sg_io(request_queue_t *q, struct block_device *bdev,
struct sg_io_hdr *uptr)
{
- unsigned long uaddr, start_time;
- int reading, writing, nr_sectors;
+ unsigned long start_time;
+ int reading, writing;
struct sg_io_hdr hdr;
struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
void *buffer;

- if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
- return -EFAULT;
if (copy_from_user(&hdr, uptr, sizeof(*uptr)))
return -EFAULT;

@@ -156,11 +157,6 @@
return -EINVAL;
if (hdr.cmd_len > sizeof(rq->cmd))
return -EINVAL;
- if (!access_ok(VERIFY_READ, hdr.cmdp, hdr.cmd_len))
- return -EFAULT;
-
- if (hdr.dxfer_len > 65536)
- return -EINVAL;

/*
* we'll do that later
@@ -168,7 +164,9 @@
if (hdr.iovec_count)
return -EOPNOTSUPP;

- nr_sectors = 0;
+ if (hdr.dxfer_len > (q->max_sectors << 9))
+ return -EIO;
+
reading = writing = 0;
buffer = NULL;
bio = NULL;
@@ -189,19 +187,12 @@
break;
}

- uaddr = (unsigned long) hdr.dxferp;
- /* writing to device -> reading from vm */
- if (writing && !access_ok(VERIFY_READ, uaddr, bytes))
- return -EFAULT;
- /* reading from device -> writing to vm */
- else if (reading && !access_ok(VERIFY_WRITE, uaddr, bytes))
- return -EFAULT;
-
/*
* first try to map it into a bio. reading from device will
* be a write to vm.
*/
- bio = bio_map_user(bdev, uaddr, hdr.dxfer_len, reading);
+ bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
+ hdr.dxfer_len, reading);

/*
* if bio setup failed, fall back to slow approach
@@ -211,10 +202,11 @@
if (!buffer)
return -ENOMEM;

- nr_sectors = bytes >> 9;
- if (writing)
- copy_from_user(buffer,hdr.dxferp,hdr.dxfer_len);
- else
+ if (writing) {
+ if (copy_from_user(buffer, hdr.dxferp,
+ hdr.dxfer_len))
+ goto out_buffer;
+ } else
memset(buffer, 0, hdr.dxfer_len);
}
}
@@ -225,7 +217,8 @@
* fill in request structure
*/
rq->cmd_len = hdr.cmd_len;
- copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len);
+ if (copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len))
+ goto out_request;
if (sizeof(rq->cmd) != hdr.cmd_len)
memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);

@@ -235,18 +228,15 @@

rq->flags |= REQ_BLOCK_PC;

- rq->hard_nr_sectors = rq->nr_sectors = nr_sectors;
- rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors;
-
- rq->bio = rq->biotail = bio;
+ rq->bio = rq->biotail = NULL;

if (bio)
blk_rq_bio_prep(q, rq, bio);

- rq->data_len = hdr.dxfer_len;
rq->data = buffer;
+ rq->data_len = hdr.dxfer_len;

- rq->timeout = hdr.timeout;
+ rq->timeout = (hdr.timeout * HZ) / 1000;
if (!rq->timeout)
rq->timeout = q->sg_timeout;
if (!rq->timeout)
@@ -273,7 +263,7 @@
if (hdr.masked_status || hdr.host_status || hdr.driver_status)
hdr.info |= SG_INFO_CHECK;
hdr.resid = rq->data_len;
- hdr.duration = (jiffies - start_time) * (1000 / HZ);
+ hdr.duration = ((jiffies - start_time) * 1000) / HZ;
hdr.sb_len_wr = 0;

if (rq->sense_len && hdr.sbp) {
@@ -286,17 +276,25 @@

blk_put_request(rq);

- copy_to_user(uptr, &hdr, sizeof(*uptr));
+ if (copy_to_user(uptr, &hdr, sizeof(*uptr)))
+ goto out_buffer;

if (buffer) {
if (reading)
- copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len);
+ if (copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len))
+ goto out_buffer;

kfree(buffer);
}
+
/* may not have succeeded, but output values written to control
* structure (struct sg_io_hdr). */
return 0;
+out_request:
+ blk_put_request(rq);
+out_buffer:
+ kfree(buffer);
+ return -EFAULT;
}

#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
===== drivers/ide/ide-cd.c 1.46 vs edited =====
--- 1.46/drivers/ide/ide-cd.c Thu May 8 10:39:34 2003
+++ edited/drivers/ide/ide-cd.c Fri May 30 14:38:59 2003
@@ -666,8 +666,10 @@
struct cdrom_info *info = drive->driver_data;
void *sense = &info->sense_data;

- if (failed && failed->sense)
+ if (failed && failed->sense) {
sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }

cdrom_analyze_sense_data(drive, failed, sense);
}
@@ -723,7 +725,7 @@
* scsi status byte
*/
if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
- rq->errors = CHECK_CONDITION;
+ rq->errors = SAM_STAT_CHECK_CONDITION;

/* Check for tray open. */
if (sense_key == NOT_READY) {
@@ -1609,10 +1611,18 @@

static void post_transform_command(struct request *req)
{
- char *ibuf = req->buffer;
u8 *c = req->cmd;
+ char *ibuf;

if (!blk_pc_request(req))
+ return;
+
+ if (req->bio)
+ ibuf = bio_data(req->bio);
+ else
+ ibuf = req->data;
+
+ if (!ibuf)
return;

/*
===== fs/bio.c 1.45 vs edited =====
--- 1.45/fs/bio.c Tue May 27 03:53:39 2003
+++ edited/fs/bio.c Fri May 30 14:32:56 2003
@@ -538,12 +538,6 @@
bio = __bio_map_user(bdev, uaddr, len, write_to_vm);

if (bio) {
- if (bio->bi_size < len) {
- bio_endio(bio, bio->bi_size, 0);
- bio_unmap_user(bio, 0);
- return NULL;
- }
-
/*
* subtle -- if __bio_map_user() ended up bouncing a bio,
* it would normally disappear when its bi_end_io is run.
@@ -551,6 +545,12 @@
* reference to it
*/
bio_get(bio);
+
+ if (bio->bi_size < len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio, 0);
+ return NULL;
+ }
}

return bio;

--
Jens Axboe


2003-05-30 13:34:39

by Markus Plail

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

Hi there!

The patch makes readcd work just fine here :-) Many thanks!

Now if only writing would also work...

regards
Markus

[15:44:31]-[Fri May 30]-[~]
[plail@plailis_lfs]dvdrecord dev=/dev/hdb speed=4 -v -dummy /video-2/trailer_final_1000_dl.mov
Cdrecord-ProDVD-Clone 2.01a12 (i586-pc-linux-gnu) Copyright (C) 1995-2003 J?rg Schilling
Unlocked features: ProDVD Clone
Limited features: speed
This copy of cdrecord is licensed for: private/research/educational_non-commercial_use
TOC Type: 1 = CD-ROM
devname: '/dev/hdb'
scsibus: -2 target: -2 lun: -2
Warning: Open by 'devname' is unintentional and not supported.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.7'
atapi: 1
Device type : Removable CD-ROM
Version : 0
Response Format: 2
Capabilities :
Vendor_info : 'TEAC '
Identifikation : 'DV-W50E '
Revision : '1.30'
Device seems to be: Generic mmc2 DVD-R/DVD-RW.
Current: DVD-RW sequential overwrite
Profile: DVD-RW sequential overwrite (current)
Profile: DVD-RW restricted overwrite (current)
Profile: DVD-R sequential recording (current)
Profile: DVD-ROM
Profile: CD-RW
Profile: CD-R
Profile: CD-ROM
Using generic SCSI-3/mmc-2 DVD-R/DVD-RW driver (mmc_dvd).
Driver flags : DVD MMC-3 SWABAUDIO BURNFREE
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R
Drive buf size : 1605632 = 1568 KB
FIFO size : 4194304 = 4096 KB
Track 01: data 97 MB
Total size: 97 MB = 49843 sectors
Current Secsize: 2048
Total power on hours: 110055
WARNING: Phys disk size 49843 differs from rzone size 2298496! Prerecorded disk?
WARNING: Phys start: 196608 Phys end 246450
Blocks total: 2298496 Blocks current: 2298496 Blocks remaining: 2248653
Starting to write CD/DVD at speed 2 in dummy TAO mode for single session.
Last chance to quit, starting dummy write 0 seconds. Operation starts.
Waiting for reader process to fill input buffer ... input buffer ready.
BURN-Free is OFF.
Starting new track at sector: 0
Track 01: 1 of 97 MB written (fifo 85%) [buf 67%] 11.5x.cdrecord-ProDVD: Success. write_g1: scsi sendcmd: no error
CDB: 2A 00 00 00 03 07 00 00 1F 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70
Sense Key: 0x0 No Additional Sense, Segment 0
Sense Code: 0x00 Qual 0x00 (no additional sense information) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 63488
cmd finished after 0.005s timeout 100s

write track data: error after 1587200 bytes
cdrecord-ProDVD: A write error occured.
cdrecord-ProDVD: Please properly read the error message above.
Writing time: 5.198s
Average write speed 14.3x.
Fixating...
Fixating time: 0.464s
cdrecord-ProDVD: fifo had 89 puts and 26 gets.
cdrecord-ProDVD: fifo was 0 times empty and 2 times full, min fill was 82%.
You have new mail in /var/mail/plail
[15:45:08]-[Fri May 30]-[~]
[plail@plailis_lfs]

2003-05-30 13:41:57

by Markus Plail

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Fri, 30 May 2003, Markus Plail wrote:

> The patch makes readcd work just fine here :-) Many thanks!

Just realized that C2 scans don't yet work.

regards
Markus

[15:49:37]-[Fri May 30]-[/home/plail]
[root@plailis_lfs]strace /opt/schily/bin/readcd dev=/dev/hdb -c2scan
execve("/opt/schily/bin/readcd", ["/opt/schily/bin/readcd", "dev=/dev/hdb", "-c2scan"], [/* 45 vars */]) = 0
brk(0) = 0x806a000
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=66034, ...}) = 0
old_mmap(NULL, 66034, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\10\332"..., 1024) = 1024
fstat64(3, {st_mode=S_IFREG|0755, st_size=5021367, ...}) = 0
old_mmap(NULL, 1215588, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40028000
mprotect(0x40146000, 44132, PROT_NONE) = 0
old_mmap(0x40146000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x11d000) = 0x40146000
old_mmap(0x4014d000, 15460, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4014d000
close(3) = 0
munmap(0x40017000, 66034) = 0
brk(0) = 0x806a000
brk(0x806a0a8) = 0x806a0a8
brk(0x806b000) = 0x806b000
brk(0x806d000) = 0x806d000
open("/dev/hdb", O_RDWR|O_NONBLOCK) = 3
fcntl64(3, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE)
fcntl64(3, F_SETFL, O_RDWR|O_LARGEFILE) = 0
ioctl(3, 0x5382, 0xbffff164) = 0
ioctl(3, 0x5386, 0xbffff160) = 0
ioctl(3, 0x2282, 0xbffff168) = 0
ioctl(3, 0x5382, 0xbffff104) = 0
ioctl(3, 0x5386, 0xbffff100) = 0
ioctl(3, 0x2201, 0xbffff018) = 0
fstat64(3, {st_mode=S_IFBLK|0660, st_rdev=makedev(3, 64), ...}) = 0
ioctl(3, 0x2272, 0xbffff338) = 0
ioctl(3, 0x2272, 0xbffff338) = 0
ioctl(3, 0x2275, 0xbffff334) = -1 EINVAL (Invalid argument)
ioctl(3, 0x2272, 0xbffff334) = 0
ioctl(3, 0x2272, 0xbffff318) = 0
ioctl(3, 0x2272, 0xbffff314) = 0
old_mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40151000
geteuid32() = 0
getuid32() = 0
getuid32() = 0
setreuid32(0xffffffff, 0) = 0
gettimeofday({1054302587, 28334}, NULL) = 0
ioctl(3, 0x2285, 0xbffff0fc) = 0
gettimeofday({1054302587, 29005}, NULL) = 0
gettimeofday({1054302587, 29274}, NULL) = 0
ioctl(3, 0x2285, 0xbffff13c) = 0
...
...[snip]...
...
ioctl(3, 0x2285, 0xbfffee8c) = 0
gettimeofday({1054302587, 141430}, NULL) = 0
write(2, "Read speed: 8310 kB/s (CD 47x"..., 44Read speed: 8310 kB/s (CD 47x, DVD 6x).
) = 44
write(2, "Write speed: 2770 kB/s (CD 15x"..., 44Write speed: 2770 kB/s (CD 15x, DVD 2x).
) = 44
rt_sigaction(SIGINT, {0x8049d48, [INT], SA_RESTART|0x4000000}, {SIG_DFL}, 8) = 0
rt_sigaction(SIGTERM, {0x8049d48, [TERM], SA_RESTART|0x4000000}, {SIG_DFL}, 8) = 0
gettimeofday({1054302587, 143382}, NULL) = 0
ioctl(3, 0x2285, 0xbffff28c) = 0
gettimeofday({1054302587, 144030}, NULL) = 0
gettimeofday({1054302587, 144315}, NULL) = 0
ioctl(3, 0x2285, 0xbffff25c) = 0
gettimeofday({1054302587, 150267}, NULL) = 0
gettimeofday({1054302587, 150526}, NULL) = 0
ioctl(3, 0x2285, 0xbffff25c) = 0
gettimeofday({1054302587, 151355}, NULL) = 0
write(2, "Capacity: 49843 Blocks = 99686 k"..., 61Capacity: 49843 Blocks = 99686 kBytes = 97 MBytes = 102 prMB
) = 61
write(2, "Sectorsize: 2048 Bytes\n", 23Sectorsize: 2048 Bytes
) = 23
gettimeofday({1054302587, 152679}, NULL) = 0
ioctl(3, 0x2285, 0xbfffedfc) = 0
gettimeofday({1054302587, 156396}, NULL) = 0
gettimeofday({1054302587, 156644}, NULL) = 0
ioctl(3, 0x2285, 0xbfffec7c) = 0
...
...[snip]...
...
ioctl(3, 0x2285, 0xbfffefcc) = 0
gettimeofday({1054302587, 244917}, NULL) = 0
write(2, "Copy from SCSI (0,0,0) disk to f"..., 48Copy from SCSI (0,0,0) disk to file '/dev/null'
) = 48
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
fcntl64(4, F_GETFL) = 0x8001 (flags O_WRONLY|O_LARGEFILE)
fstat64(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE, 0xbfffedb8) = -1 ENOTTY (Inappropriate ioctl for device)
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000
_llseek(4, 0, [0], SEEK_CUR) = 0
munmap(0x40017000, 4096) = 0
write(2, "end: 49843\n", 15end: 49843
) = 15
gettimeofday({1054302587, 248522}, NULL) = 0
) = 232, "addr: 0 cnt: 48\r", 23addr: 0 cnt: 48
gettimeofday({1054302587, 249061}, NULL) = 0
ioctl(3, 0x2285, 0xbfffef6c) = 0
gettimeofday({1054302587, 259824}, NULL) = 0
write(2, "/opt/schily/bin/readcd: Success."..., 352/opt/schily/bin/readcd: Success. read_cd: scsi sendcmd: no error
CDB: BE 00 00 00 00 00 00 00 30 FA 00 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70
Sense Key: 0x0 No Additional Sense, Segment 0
Sense Code: 0x00 Qual 0x00 (no additional sense information) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 127008
cmd finished after 0.010s timeout 40s
) = 352
write(2, "/opt/schily/bin/readcd: Success."..., 57/opt/schily/bin/readcd: Success. Cannot read source disk
) = 57
write(2, "/opt/schily/bin/readcd: Retrying"..., 48/opt/schily/bin/readcd: Retrying from sector 0.
) = 48
write(2, ".", 1.) = 1
gettimeofday({1054302587, 262470}, NULL) = 0
ioctl(3, 0x2285, 0xbfffcf4c) = 0
gettimeofday({1054302587, 263143}, NULL) = 0
gettimeofday({1054302587, 263402}, NULL) = 0


2003-05-30 14:45:45

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Fri, May 30 2003, Markus Plail wrote:
> On Fri, 30 May 2003, Markus Plail wrote:
>
> > The patch makes readcd work just fine here :-) Many thanks!
>
> Just realized that C2 scans don't yet work.

Updated patch, please give that a shot. These sense_len wasn't being set
correctly.

===== drivers/block/ioctl.c 1.54 vs edited =====
--- 1.54/drivers/block/ioctl.c Sat Apr 26 00:16:28 2003
+++ edited/drivers/block/ioctl.c Fri May 30 10:25:55 2003
@@ -207,11 +207,8 @@
set_device_ro(bdev, n);
return 0;
default:
- if (disk->fops->ioctl) {
- ret = disk->fops->ioctl(inode, file, cmd, arg);
- if (ret != -EINVAL)
- return ret;
- }
+ if (disk->fops->ioctl)
+ return disk->fops->ioctl(inode, file, cmd, arg);
}
return -ENOTTY;
}
===== drivers/block/scsi_ioctl.c 1.27 vs edited =====
--- 1.27/drivers/block/scsi_ioctl.c Sat May 17 12:05:21 2003
+++ edited/drivers/block/scsi_ioctl.c Fri May 30 16:57:36 2003
@@ -68,7 +68,6 @@

rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
- drive_stat_acct(rq, rq->nr_sectors, 1);
elv_add_request(q, rq, 1, 1);
generic_unplug_device(q);
wait_for_completion(&wait);
@@ -99,7 +98,7 @@

static int sg_get_timeout(request_queue_t *q)
{
- return q->sg_timeout;
+ return q->sg_timeout / (HZ / USER_HZ);
}

static int sg_set_timeout(request_queue_t *q, int *p)
@@ -107,7 +106,7 @@
int timeout, err = get_user(timeout, p);

if (!err)
- q->sg_timeout = timeout;
+ q->sg_timeout = timeout * (HZ / USER_HZ);

return err;
}
@@ -121,10 +120,14 @@
{
int size, err = get_user(size, p);

- if (!err)
- q->sg_reserved_size = size;
+ if (err)
+ return err;

- return err;
+ if (size > (q->max_sectors << 9))
+ return -EINVAL;
+
+ q->sg_reserved_size = size;
+ return 0;
}

/*
@@ -139,16 +142,14 @@
static int sg_io(request_queue_t *q, struct block_device *bdev,
struct sg_io_hdr *uptr)
{
- unsigned long uaddr, start_time;
- int reading, writing, nr_sectors;
+ unsigned long start_time;
+ int reading, writing;
struct sg_io_hdr hdr;
struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
void *buffer;

- if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
- return -EFAULT;
if (copy_from_user(&hdr, uptr, sizeof(*uptr)))
return -EFAULT;

@@ -156,11 +157,6 @@
return -EINVAL;
if (hdr.cmd_len > sizeof(rq->cmd))
return -EINVAL;
- if (!access_ok(VERIFY_READ, hdr.cmdp, hdr.cmd_len))
- return -EFAULT;
-
- if (hdr.dxfer_len > 65536)
- return -EINVAL;

/*
* we'll do that later
@@ -168,7 +164,9 @@
if (hdr.iovec_count)
return -EOPNOTSUPP;

- nr_sectors = 0;
+ if (hdr.dxfer_len > (q->max_sectors << 9))
+ return -EIO;
+
reading = writing = 0;
buffer = NULL;
bio = NULL;
@@ -189,19 +187,12 @@
break;
}

- uaddr = (unsigned long) hdr.dxferp;
- /* writing to device -> reading from vm */
- if (writing && !access_ok(VERIFY_READ, uaddr, bytes))
- return -EFAULT;
- /* reading from device -> writing to vm */
- else if (reading && !access_ok(VERIFY_WRITE, uaddr, bytes))
- return -EFAULT;
-
/*
* first try to map it into a bio. reading from device will
* be a write to vm.
*/
- bio = bio_map_user(bdev, uaddr, hdr.dxfer_len, reading);
+ bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
+ hdr.dxfer_len, reading);

/*
* if bio setup failed, fall back to slow approach
@@ -211,10 +202,11 @@
if (!buffer)
return -ENOMEM;

- nr_sectors = bytes >> 9;
- if (writing)
- copy_from_user(buffer,hdr.dxferp,hdr.dxfer_len);
- else
+ if (writing) {
+ if (copy_from_user(buffer, hdr.dxferp,
+ hdr.dxfer_len))
+ goto out_buffer;
+ } else
memset(buffer, 0, hdr.dxfer_len);
}
}
@@ -225,7 +217,8 @@
* fill in request structure
*/
rq->cmd_len = hdr.cmd_len;
- copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len);
+ if (copy_from_user(rq->cmd, hdr.cmdp, hdr.cmd_len))
+ goto out_request;
if (sizeof(rq->cmd) != hdr.cmd_len)
memset(rq->cmd + hdr.cmd_len, 0, sizeof(rq->cmd) - hdr.cmd_len);

@@ -235,18 +228,15 @@

rq->flags |= REQ_BLOCK_PC;

- rq->hard_nr_sectors = rq->nr_sectors = nr_sectors;
- rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors;
-
- rq->bio = rq->biotail = bio;
+ rq->bio = rq->biotail = NULL;

if (bio)
blk_rq_bio_prep(q, rq, bio);

- rq->data_len = hdr.dxfer_len;
rq->data = buffer;
+ rq->data_len = hdr.dxfer_len;

- rq->timeout = hdr.timeout;
+ rq->timeout = (hdr.timeout * HZ) / 1000;
if (!rq->timeout)
rq->timeout = q->sg_timeout;
if (!rq->timeout)
@@ -273,12 +263,11 @@
if (hdr.masked_status || hdr.host_status || hdr.driver_status)
hdr.info |= SG_INFO_CHECK;
hdr.resid = rq->data_len;
- hdr.duration = (jiffies - start_time) * (1000 / HZ);
+ hdr.duration = ((jiffies - start_time) * 1000) / HZ;
hdr.sb_len_wr = 0;

if (rq->sense_len && hdr.sbp) {
- int len = (hdr.mx_sb_len < rq->sense_len) ?
- hdr.mx_sb_len : rq->sense_len;
+ int len = min((unsigned int) hdr.mx_sb_len, rq->sense_len);

if (!copy_to_user(hdr.sbp, rq->sense, len))
hdr.sb_len_wr = len;
@@ -286,17 +275,25 @@

blk_put_request(rq);

- copy_to_user(uptr, &hdr, sizeof(*uptr));
+ if (copy_to_user(uptr, &hdr, sizeof(*uptr)))
+ goto out_buffer;

if (buffer) {
if (reading)
- copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len);
+ if (copy_to_user(hdr.dxferp, buffer, hdr.dxfer_len))
+ goto out_buffer;

kfree(buffer);
}
+
/* may not have succeeded, but output values written to control
* structure (struct sg_io_hdr). */
return 0;
+out_request:
+ blk_put_request(rq);
+out_buffer:
+ kfree(buffer);
+ return -EFAULT;
}

#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
===== drivers/ide/ide-cd.c 1.46 vs edited =====
--- 1.46/drivers/ide/ide-cd.c Thu May 8 10:39:34 2003
+++ edited/drivers/ide/ide-cd.c Fri May 30 16:54:11 2003
@@ -666,8 +666,10 @@
struct cdrom_info *info = drive->driver_data;
void *sense = &info->sense_data;

- if (failed && failed->sense)
+ if (failed && failed->sense) {
sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }

cdrom_analyze_sense_data(drive, failed, sense);
}
@@ -723,7 +725,7 @@
* scsi status byte
*/
if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
- rq->errors = CHECK_CONDITION;
+ rq->errors = SAM_STAT_CHECK_CONDITION;

/* Check for tray open. */
if (sense_key == NOT_READY) {
@@ -1471,8 +1476,9 @@
/* Keep count of how much data we've moved. */
rq->data += thislen;
rq->data_len -= thislen;
- if (rq->cmd[0] == GPCMD_REQUEST_SENSE)
- rq->sense_len++;
+
+ if (rq->flags & REQ_SENSE)
+ rq->sense_len += thislen;
} else {
confused:
printk ("%s: cdrom_pc_intr: The drive "
@@ -1609,10 +1615,18 @@

static void post_transform_command(struct request *req)
{
- char *ibuf = req->buffer;
u8 *c = req->cmd;
+ char *ibuf;

if (!blk_pc_request(req))
+ return;
+
+ if (req->bio)
+ ibuf = bio_data(req->bio);
+ else
+ ibuf = req->data;
+
+ if (!ibuf)
return;

/*
===== fs/bio.c 1.45 vs edited =====
--- 1.45/fs/bio.c Tue May 27 03:53:39 2003
+++ edited/fs/bio.c Fri May 30 14:32:56 2003
@@ -538,12 +538,6 @@
bio = __bio_map_user(bdev, uaddr, len, write_to_vm);

if (bio) {
- if (bio->bi_size < len) {
- bio_endio(bio, bio->bi_size, 0);
- bio_unmap_user(bio, 0);
- return NULL;
- }
-
/*
* subtle -- if __bio_map_user() ended up bouncing a bio,
* it would normally disappear when its bi_end_io is run.
@@ -551,6 +545,12 @@
* reference to it
*/
bio_get(bio);
+
+ if (bio->bi_size < len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio, 0);
+ return NULL;
+ }
}

return bio;

--
Jens Axboe

2003-05-30 16:44:01

by Markus Plail

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Fri, 30 May 2003, Jens Axboe wrote:

> On Fri, May 30 2003, Markus Plail wrote:
>> On Fri, 30 May 2003, Markus Plail wrote:
>> > The patch makes readcd work just fine here :-) Many thanks!
>>
>> Just realized that C2 scans don't yet work.
>
> Updated patch, please give that a shot. These sense_len wasn't being
> set correctly.

Works fine for readcd and cdrecord (same with CD and DVD) now exits in
another way.

regards
Markus

[plail@plailis_lfs]dvdrecord dev=/dev/hdb speed=4 -v -dao driveropts=burnfree -dummy /video-2/trailer_final_1000_dl.mov Cdrecord-ProDVD-Clone 2.01a12 (i586-pc-linux-gnu) Copyright (C) 1995-2003 J?rg Schilling
Unlocked features: ProDVD Clone
Limited features: speed
This copy of cdrecord is licensed for: private/research/educational_non-commercial_use
TOC Type: 1 = CD-ROM
scsidev: '/dev/hdb'
devname: '/dev/hdb'
scsibus: -2 target: -2 lun: -2
Warning: Open by 'devname' is unintentional and not supported.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.7'
Driveropts: 'burnfree'
atapi: 1
Device type : Removable CD-ROM
Version : 0
Response Format: 2
Capabilities :
Vendor_info : 'TEAC '
Identifikation : 'DV-W50E '
Revision : '1.30'
Device seems to be: Generic mmc2 DVD-R/DVD-RW.
Current: DVD-RW sequential overwrite
Profile: DVD-RW sequential overwrite (current)
Profile: DVD-RW restricted overwrite (current)
Profile: DVD-R sequential recording (current)
Profile: DVD-ROM
Profile: CD-RW
Profile: CD-R
Profile: CD-ROM
Using generic SCSI-3/mmc-2 DVD-R/DVD-RW driver (mmc_dvd).
Driver flags : DVD MMC-3 SWABAUDIO BURNFREE
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R
Drive buf size : 1605632 = 1568 KB
FIFO size : 4194304 = 4096 KB
Track 01: data 97 MB
Total size: 97 MB = 49843 sectors
Current Secsize: 2048
Total power on hours: 110150
Blocks total: 2298496 Blocks current: 2298496 Blocks remaining: 2248653
Starting to write CD/DVD at speed 2 in dummy SAO mode for single session.
Last chance to quit, starting dummy write 0 seconds. Operation starts.
Waiting for reader process to fill input buffer ... input buffer ready.
BURN-Free is ON.
Starting new track at sector: 0
Track 01: 1 of 97 MB written (fifo 96%) [buf 67%] 10.5x.cdrecord-ProDVD: Success. write_g1: scsi sendcmd: no error
CDB: 2A 00 00 00 03 64 00 00 1F 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70 00 05 00 00 00 00 0E 00 00 00 00 21 02 00 00
Sense Key: 0x5 Illegal Request, Segment 0
Sense Code: 0x21 Qual 0x02 (invalid address for write) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 63488
cmd finished after 0.006s timeout 100s

write track data: error after 1777664 bytes
cdrecord-ProDVD: The current problem looks like a buffer underrun.
cdrecord-ProDVD: It looks like 'driveropts=burnfree' does not work for this drive.
cdrecord-ProDVD: Please report.
cdrecord-ProDVD: Make sure that you are root, enable DMA and check your HW/OS set up.
Writing time: 46.904s
Average write speed 15.0x.
Fixating...
WARNING: Some drives don't like fixation in dummy mode.
Fixating time: 1.528s
cdrecord-ProDVD: fifo had 95 puts and 32 gets.
cdrecord-ProDVD: fifo was 0 times empty and 19 times full, min fill was 92%.
You have new mail in /var/mail/plail
[18:49:09]-[Fri May 30]-[~]



[root@plailis_lfs]strace /opt/schily/bin/cdrecord dev=/dev/hdb speed=4 -v -dao driveropts=burnfree -dummy /video-2/trailer_final_1000_dl.mov
execve("/opt/schily/bin/cdrecord", ["/opt/schily/bin/cdrecord", "dev=/dev/hdb", "speed=4", "-v", "-dao", "driveropts=burnfree", "-dummy", "/video-2/trailer_final_1000_dl.mov"], [/* 45 vars */]) = 0
brk(0) = 0x8099000
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=66034, ...}) = 0
old_mmap(NULL, 66034, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\10\332"..., 1024) = 1024
fstat64(3, {st_mode=S_IFREG|0755, st_size=5021367, ...}) = 0
old_mmap(NULL, 1215588, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40028000
mprotect(0x40146000, 44132, PROT_NONE) = 0
old_mmap(0x40146000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x11d000) = 0x40146000
old_mmap(0x4014d000, 15460, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4014d000
close(3) = 0
munmap(0x40017000, 66034) = 0
getrlimit(0x7, 0xbfffcee4) = 0
brk(0) = 0x8099000
brk(0x8099180) = 0x8099180
brk(0x809a000) = 0x809a000
open("/etc/default/cdrecord", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40017000
write(1, "Cdrecord 2.01a15 (i686-pc-linux-"..., 76Cdrecord 2.01a15 (i686-pc-linux-gnu) Copyright (C) 1995-2003 J?rg Schilling
) = 76
fstat64(2, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0

...
...[snip]
...

gettimeofday({1054313438, 700025}, NULL) = 0
ioctl(3, 0x2285, 0xbfffcd0c) = 0
gettimeofday({1054313438, 706685}, NULL) = 0
write(2, "/opt/schily/bin/cdrecord: Succes"..., 384/opt/schily/bin/cdrecord: Success. write_g1: scsi sendcmd: no error
CDB: 2A 00 00 00 03 07 00 00 1F 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70 00 05 00 00 00 00 0E 00 00 00 00 21 02 00 00
Sense Key: 0x5 Illegal Request, Segment 0
Sense Code: 0x21 Qual 0x02 (invalid address for write) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 63488
cmd finished after 0.006s timeout 200s
) = 384
write(1, "\nwrite track data: error after 1"..., 45
write track data: error after 1587200 bytes
) = 45
write(2, "/opt/schily/bin/cdrecord: The cu"..., 76/opt/schily/bin/cdrecord: The current problem looks like a buffer underrun.
) = 76
write(2, "/opt/schily/bin/cdrecord: It loo"..., 92/opt/schily/bin/cdrecord: It looks like 'driveropts=burnfree' does not work for this drive.
) = 92
write(2, "/opt/schily/bin/cdrecord: Please"..., 41/opt/schily/bin/cdrecord: Please report.
) = 41
write(2, "/opt/schily/bin/cdrecord: Make s"..., 95/opt/schily/bin/cdrecord: Make sure that you are root, enable DMA and check your HW/OS set up.
) = 95
rt_sigprocmask(SIG_BLOCK, [CHLD], [RTMIN], 8) = 0

2003-05-31 08:11:30

by Douglas Gilbert

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

--- linux/drivers/block/scsi_ioctl.c 2003-05-31 13:50:04.000000000 +1000
+++ linux/drivers/block/scsi_ioctl.c2570dpg2 2003-05-31 14:13:15.000000000 +1000
@@ -82,7 +82,7 @@

static int sg_get_version(int *p)
{
- static int sg_version_num = 30527;
+ static int sg_version_num = 30729; /* version 3.7.* to distinguish */
return put_user(sg_version_num, p);
}

@@ -143,7 +143,7 @@
struct sg_io_hdr *uptr)
{
unsigned long start_time;
- int reading, writing;
+ int reading, writing, dio;
struct sg_io_hdr hdr;
struct request *rq;
struct bio *bio;
@@ -163,11 +163,14 @@
*/
if (hdr.iovec_count)
return -EOPNOTSUPP;
+ if (hdr.flags & SG_FLAG_MMAP_IO)
+ return -EOPNOTSUPP;

if (hdr.dxfer_len > (q->max_sectors << 9))
return -EIO;

reading = writing = 0;
+ dio = 0;
buffer = NULL;
bio = NULL;
if (hdr.dxfer_len) {
@@ -194,10 +197,12 @@
bio = bio_map_user(bdev, (unsigned long) hdr.dxferp,
hdr.dxfer_len, reading);

- /*
- * if bio setup failed, fall back to slow approach
- */
- if (!bio) {
+ if (bio)
+ dio = 1;
+ else {
+ /*
+ * if bio setup failed, fall back to slow approach
+ */
buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER);
if (!buffer)
return -ENOMEM;
@@ -206,8 +211,11 @@
if (copy_from_user(buffer, hdr.dxferp,
hdr.dxfer_len))
goto out_buffer;
+ if (bytes > hdr.dxfer_len)
+ memset((char *)buffer + hdr.dxfer_len,
+ 0, bytes - hdr.dxfer_len);
} else
- memset(buffer, 0, hdr.dxfer_len);
+ memset(buffer, 0, bytes);
}
}

@@ -257,11 +265,13 @@
hdr.status = rq->errors;
hdr.masked_status = (hdr.status >> 1) & 0x1f;
hdr.msg_status = 0;
- hdr.host_status = 0;
+ hdr.host_status = 0; /* "lost nexus" error could go here */
hdr.driver_status = 0;
hdr.info = 0;
if (hdr.masked_status || hdr.host_status || hdr.driver_status)
hdr.info |= SG_INFO_CHECK;
+ if (dio && (hdr.flags & SG_FLAG_DIRECT_IO))
+ hdr.info |= SG_INFO_DIRECT_IO;
hdr.resid = rq->data_len;
hdr.duration = ((jiffies - start_time) * 1000) / HZ;
hdr.sb_len_wr = 0;
@@ -286,7 +296,7 @@
kfree(buffer);
}

- /* may not have succeeded, but output values written to control
+ /* may not have succeeded, but output status written to control
* structure (struct sg_io_hdr). */
return 0;
out_request:


Attachments:
blk_sg_io2570ja_dg.diff (2.28 kB)

2003-05-31 10:44:24

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Sat, May 31 2003, Douglas Gilbert wrote:
> Jens Axboe wrote:
> > On Fri, May 30 2003, Markus Plail wrote:
> > > On Fri, 30 May 2003, Markus Plail wrote:
> > >
> > > > The patch makes readcd work just fine here :-) Many thanks!
> > >
> > > Just realized that C2 scans don't yet work.
> >
> > Updated patch, please give that a shot. These sense_len wasn't
> > being set correctly.
>
> Jens,
> At the end of this post is an incremental patch on
> top of your most recent one.

(Douglas, please don't sent seperate identical mails in private and to
the lists, it's silly having to reply twice to the same mail).

> Here are some timing and CPU utilization numbers on the
> combined patches. Reading
> 1 GB data from the beginning of a Fujitsu MAM3184MP SCSI
> disk whose streaming speed for outer zones is about
> 57 MB/sec (according to Storage Review). Each atomic read
> is 64 KB (and "of=." is sg_dd shorthand for "of=/dev/null").
>
> Here is a normal read (i.e. treating /dev/sda as a normal file):
> $ /usr/bin/time sg_dd if=/dev/sda of=. bs=512 time=1 count=2M
> time to transfer data was 17.821534 secs, 57.46 MB/sec
> 0.00user 4.37system 0:17.82elapsed 24%CPU
>
> The transfer time is a little fast due to cache hits. The
> 24% CPU utilization is the price paid for those cache hits.
>
> Next using O_DIRECT:
> $ /usr/bin/time sg_dd if=/dev/sda of=. bs=512 time=1 count=2M
> odir=1
> time to transfer data was 18.003662 secs, 56.88 MB/sec
> 0.00user 0.52system 0:18.00elapsed 2%CPU
>
> The time to transfer is about right and the CPU utilization is
> down to 2% (0.52 seconds).
>
> Next using the block layer SG_IO command:
> $ /usr/bin/time sg_dd if=/dev/sda of=. bs=512 time=1 count=2M
> blk_sgio=1
> time to transfer data was 18.780551 secs, 54.52 MB/sec
> 0.00user 6.40system 0:18.78elapsed 34%CPU
>
> The throughput is worse and the CPU utilization is now
> worse than a normal file.
>
> Setting the "dio=1" flag in sg_dd page aligns its buffers
> which causes bio_map_user() to succeed (in
> drivers/block/scsi_ioctl.c:sg_io()). In other words it turns
> on direct I/O:
> $ /usr/bin/time sg_dd if=/dev/sda of=. bs=512 time=1 count=2M
> blk_sgio=1 dio=1
> time to transfer data was 17.899802 secs, 57.21 MB/sec
> 0.00user 0.31system 0:17.90elapsed 1%CPU

This looks fine, a performance critical app should align the buffers to
get zero copy operation.

> So this result is comparable with O_DIRECT on the normal
> file. CPU utilization is down to 1% (0.31 seonds).

A smidgen faster, it seems.

> With the latest changes from Jens (mainly dropping the
> artificial 64 KB per operation limit) the maximum
> element size in the block layer SG_IO is:
> - 128 KB when direct I/O is not used (i.e. the user
> space buffer does not meet bio_map_user()'s
> requirements). This seems to be the largest buffer
> kmalloc() will allow (in my tests)

Correct.

> - (sg_tablesize * page_size) when direct I/O is used.
> My test was with the sym53c8xx_2 driver in which
> sg_tablesize==96 so my largest element size was 384 KB

Or ->max_sectors << 9, whichever is smallest. Really, the limits are in
the queue. Don't confuse SCSI with block.

> Incremental patch (on top of Jens's 2nd patch in this
> thread) changelog:
> - change version number (effectively to 3.7.29) so
> apps can distinguish if the want (current sg driver
> version is 3.5.29). The main thing that app do is
> check the version >= 3.0.0 as that implies the
> SG_IO ioctl is there.

Agree

> - reject requests for mmap()-ed I/O with a "not
> supported error"

Agree

> - if direct I/O is requested, send back via info
> field whether it was done (or fell back to indirect
> I/O). This is what happens in the sg driver.

Agree

> - ultra-paranoid buffer zeroing (in padding at end)

Pointless, we wont be copying that data back. So it's a waste of cycles.

--
Jens Axboe

2003-06-01 07:37:04

by uaca

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs


Hi all

I tested 2.5.70 with scsi-ioctl-2 patch

It works fine until It has to read the last sectors.
I get the following messages from readcd, using different CD-Rs

agapito:~# readcd dev=/dev/hdc f=/dev/null
Read speed: 8450 kB/s (CD 48x, DVD 6x).
Write speed: 7056 kB/s (CD 40x, DVD 5x).
Capacity: 353137 Blocks = 706274 kBytes = 689 MBytes = 723 prMB
Sectorsize: 2048 Bytes
Copy from SCSI (0,0,0) disk to file '/dev/null'
end: 353137
readcd: Success. read_g1: scsi sendcmd: no error
CDB: 28 00 00 05 63 5B 00 00 16 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70 00 05 00 00 00 00 0A 00 00 00 00 64 00 00 00
Sense Key: 0x5 Illegal Request, Segment 0
Sense Code: 0x64 Qual 0x00 (illegal mode for this track) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 45056
cmd finished after 3.267s timeout 40s
readcd: Success. Cannot read source disk
readcd: Retrying from sector 353115.
.....................~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~
readcd: Success. Error on sector 353135 not corrected. Total of 1 errors.

Time total: 1094.406sec
Read 706230.00 kB at 645.3 kB/sec.

agapito:~# readcd dev=/dev/hdc f=/dev/null
Read speed: 8450 kB/s (CD 48x, DVD 6x).
Write speed: 7056 kB/s (CD 40x, DVD 5x).
Capacity: 355841 Blocks = 711682 kBytes = 695 MBytes = 728 prMB
Sectorsize: 2048 Bytes
Copy from SCSI (0,0,0) disk to file '/dev/null'
end: 355841
readcd: Success. read_g1: scsi sendcmd: no error
CDB: 28 00 00 05 6D F0 00 00 11 00
status: 0x2 (CHECK CONDITION)
Sense Bytes: 70 00 05 00 00 00 00 0A 00 00 00 00 64 00 00 00
Sense Key: 0x5 Illegal Request, Segment 0
Sense Code: 0x64 Qual 0x00 (illegal mode for this track) Fru 0x0
Sense flags: Blk 0 (not valid)
resid: 34816
cmd finished after 2.965s timeout 40s
readcd: Success. Cannot read source disk
readcd: Retrying from sector 355824.
................~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~+~~~-~~~
readcd: Success. Error on sector 355839 not corrected. Total of 1 errors.

Time total: 1058.468sec
Read 711648.00 kB at 672.3 kB/sec.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

dmesg shows several
hdc: confused, missing data
and then (sometimes)
cdrom_newpc_intr: 2048 residual after xfer
for each run of readcd

readcd version comes from

ulisses@agapito:~$ dpkg -l | grep cdrecord
ii cdrecord 2.0+a14-1 A command line CD writing tool


the CDR/W recorder is not the best thing on this world...
agapito:~# cdrecord dev=/dev/hdc -checkdrive
Cdrecord 2.01a14 (i686-pc-linux-gnu) Copyright (C) 1995-2003 J?rg Schilling
scsidev: '/dev/hdc'
devname: '/dev/hdc'
scsibus: -2 target: -2 lun: -2
Warning: Open by 'devname' is unintentional and not supported.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.7'
Device type : Removable CD-ROM
Version : 0
Response Format: 1
Vendor_info : 'Polaroid'
Identifikation : 'BurnMAX48 '
Revision : '482E'
Device seems to be: Generic mmc CD-RW.
Using generic SCSI-3/mmc CD-R/CD-RW driver (mmc_cdr).
Driver flags : MMC-2 SWABAUDIO BURNFREE
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R

Can I do anything else?

Ulisses

Debian GNU/Linux: a dream come true
-----------------------------------------------------------------------------
"Computers are useless. They can only give answers." Pablo Picasso

---> Visita http://www.valux.org/ para saber acerca de la <---
---> Asociaci?n Valenciana de Usuarios de Linux <---

2003-06-01 09:05:30

by Markus Plail

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Sun, 1 Jun 2003, [email protected] wrote:

> I tested 2.5.70 with scsi-ioctl-2 patch
>
> It works fine until It has to read the last sectors.
> I get the following messages from readcd, using different CD-Rs

This is just normal. Either the CD-Rs are burned in TAO mode or your
writer has problems with DAO (mine has the same problems). See
README.verify. Every such disc has two unreadable "run-out" sectors. If
this happens with -dao, try -raw96r.

HTH
Markus

BTW: Can you successsfully burn CD-Rs with > 2.5.45? If so, could you
send me your .config please?

2003-06-01 10:06:55

by uaca

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

Hi Markus

On Sun, Jun 01, 2003 at 11:18:52AM +0200, Markus Plail wrote:
> On Sun, 1 Jun 2003, [email protected] wrote:
>
> > I tested 2.5.70 with scsi-ioctl-2 patch
> >
> > It works fine until It has to read the last sectors.
> > I get the following messages from readcd, using different CD-Rs
>
> This is just normal. Either the CD-Rs are burned in TAO mode or your
> writer has problems with DAO (mine has the same problems). See
> README.verify. Every such disc has two unreadable "run-out" sectors. If
> this happens with -dao, try -raw96r.

Ok, I previously read about it in README.copy but I did misunderstud it, thanks for
your clarification

> BTW: Can you successsfully burn CD-Rs with > 2.5.45? If so, could you
> send me your .config please?

I never had problems burning successfully in TAO mode with kernel > 2.5.5X. Please note,
I still have not used the writer in dao/raw96* mode (or don't remember). I included the
config after the signature, It's a simple sis735 IDE system.

I have stabily problems in the system but I belive it's a graphic card problem
(or heat that causes it)

I will report more about it when I make some copy

Ulisses

-----------------------------------------------------------------------------
"Computers are useless. They can only give answers." Pablo Picasso

---> Visita http://www.valux.org/ para saber acerca de la <---
---> Asociaci?n Valenciana de Usuarios de Linux <---

this is 2.5.70scsi-ioctl-2

#
# Automatically generated make config: don't edit
#
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y

#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y

#
# General setup
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_EMBEDDED is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y

#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y

#
# Processor type and features
#
CONFIG_X86_PC=y
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
CONFIG_MK7=y
# CONFIG_MK8 is not set
# CONFIG_MELAN is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_X86_USE_3DNOW=y
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_SMP is not set
CONFIG_PREEMPT=y
# CONFIG_X86_UP_APIC is not set
CONFIG_X86_TSC=y
# CONFIG_X86_MCE is not set
# CONFIG_TOSHIBA is not set
# CONFIG_I8K is not set
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
# CONFIG_EDD is not set
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
CONFIG_HAVE_DEC_LOCK=y

#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
# CONFIG_SOFTWARE_SUSPEND is not set

#
# ACPI Support
#
CONFIG_ACPI=y
CONFIG_ACPI_BOOT=y
# CONFIG_ACPI_AC is not set
# CONFIG_ACPI_BATTERY is not set
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_TOSHIBA is not set
# CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_BUS=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_APM is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_PCI_NAMES=y
# CONFIG_ISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
# CONFIG_HOTPLUG is not set

#
# Executable file formats
#
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m

#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set

#
# Parallel port support
#
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_PC_CML1=m
# CONFIG_PARPORT_SERIAL is not set
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y

#
# Plug and Play support
#
# CONFIG_PNP is not set

#
# Block devices
#
CONFIG_BLK_DEV_FD=m
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_LBD is not set

#
# ATA/ATAPI/MFM/RLL device support
#
CONFIG_IDE=y

#
# IDE, ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y

#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
CONFIG_BLK_DEV_IDECD=m
# CONFIG_BLK_DEV_IDEFLOPPY is not set
CONFIG_BLK_DEV_IDESCSI=m
# CONFIG_IDE_TASK_IOCTL is not set

#
# IDE chipset support/bugfixes
#
# CONFIG_BLK_DEV_CMD640 is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
CONFIG_BLK_DEV_SIS5513=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_IDEDMA_IVB is not set
CONFIG_BLK_DEV_IDE_MODES=y

#
# SCSI device support
#
CONFIG_SCSI=m

#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m

#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_REPORT_LUNS is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set

#
# SCSI low-level drivers
#
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_NCR53C8XX is not set
# CONFIG_SCSI_SYM53C8XX is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set

#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set

#
# Fusion MPT device support
#

#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
#
# CONFIG_IEEE1394 is not set

#
# I2O device support
#
# CONFIG_I2O is not set

#
# Networking support
#
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set

#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
CONFIG_IP_NF_TFTP=m
CONFIG_IP_NF_AMANDA=m
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_MAC=m
CONFIG_IP_NF_MATCH_PKTTYPE=m
CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_DSCP=m
CONFIG_IP_NF_MATCH_AH_ESP=m
CONFIG_IP_NF_MATCH_LENGTH=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_MATCH_TCPMSS=m
CONFIG_IP_NF_MATCH_HELPER=m
CONFIG_IP_NF_MATCH_STATE=m
CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_UNCLEAN=m
CONFIG_IP_NF_MATCH_OWNER=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_MIRROR=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
CONFIG_IP_NF_NAT_LOCAL=y
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_NAT_TFTP=m
CONFIG_IP_NF_NAT_AMANDA=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
CONFIG_IP_NF_TARGET_DSCP=m
CONFIG_IP_NF_TARGET_MARK=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_COMPAT_IPCHAINS=m
CONFIG_IP_NF_COMPAT_IPFWADM=m
# CONFIG_IPV6 is not set
# CONFIG_XFRM_USER is not set

#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set

#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NETDEVICES=y

#
# ARCnet devices
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set

#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set

#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
CONFIG_SIS900=y
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set

#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set

#
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set

#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set

#
# Token Ring devices (depends on LLC=y)
#
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set

#
# Wan interfaces
#
# CONFIG_WAN is not set

#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set

#
# IrDA (infrared) support
#
# CONFIG_IRDA is not set

#
# ISDN subsystem
#
# CONFIG_ISDN_BOOL is not set

#
# Telephony Support
#
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=m
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input I/O drivers
#
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not set
# CONFIG_SERIAL_8250_EXTENDED is not set

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set

#
# I2C support
#
# CONFIG_I2C is not set

#
# I2C Hardware Sensors Mainboard support
#

#
# I2C Hardware Sensors Chip support
#
# CONFIG_I2C_SENSOR is not set

#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set

#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set

#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
CONFIG_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set

#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
CONFIG_AGP=y
# CONFIG_AGP_ALI is not set
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD_8151 is not set
# CONFIG_AGP_INTEL is not set
# CONFIG_AGP_NVIDIA is not set
CONFIG_AGP_SIS=y
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
CONFIG_DRM=y
CONFIG_DRM_TDFX=y
# CONFIG_DRM_GAMMA is not set
# CONFIG_DRM_R128 is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_MGA is not set
# CONFIG_MWAVE is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set

#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set

#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set

#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
# CONFIG_EXT2_FS_SECURITY is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
CONFIG_UDF_FS=m

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_NTFS_FS=m
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y

#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set

#
# Network File Systems
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFS_V4=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
CONFIG_NFSD_V4=y
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_SUNRPC=m
# CONFIG_SUNRPC_GSS is not set
CONFIG_SMB_FS=m
# CONFIG_SMB_NLS_DEFAULT is not set
CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_SMB_NLS=y
CONFIG_NLS=y

#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set

#
# Graphics support
#
# CONFIG_FB is not set
# CONFIG_VIDEO_SELECT is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y

#
# Sound
#
CONFIG_SOUND=y

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
CONFIG_SND_SEQUENCER=y
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_RTCTIMER=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set

#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set

#
# PCI devices
#
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
CONFIG_SND_INTEL8X0=y
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set

#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set

#
# USB support
#
# CONFIG_USB is not set
# CONFIG_USB_GADGET is not set

#
# Bluetooth support
#
# CONFIG_BT is not set

#
# Profiling support
#
# CONFIG_PROFILING is not set

#
# Kernel hacking
#
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_KALLSYMS is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_FRAME_POINTER is not set

#
# Security options
#
CONFIG_SECURITY=y
# CONFIG_SECURITY_NETWORK is not set
# CONFIG_SECURITY_CAPABILITIES is not set
# CONFIG_SECURITY_ROOTPLUG is not set

#
# Cryptographic options
#
# CONFIG_CRYPTO is not set

#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_X86_BIOS_REBOOT=y

2003-06-01 12:26:34

by Douglas Gilbert

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

Jens Axboe wrote:
> On Sat, May 31 2003, Douglas Gilbert wrote:

>>With the latest changes from Jens (mainly dropping the
>>artificial 64 KB per operation limit) the maximum
>>element size in the block layer SG_IO is:
>> - 128 KB when direct I/O is not used (i.e. the user
>> space buffer does not meet bio_map_user()'s
>> requirements). This seems to be the largest buffer
>> kmalloc() will allow (in my tests)
>
>
> Correct.
>
>
>> - (sg_tablesize * page_size) when direct I/O is used.
>> My test was with the sym53c8xx_2 driver in which
>> sg_tablesize==96 so my largest element size was 384 KB
>
>
> Or ->max_sectors << 9, whichever is smallest. Really, the limits are in
> the queue. Don't confuse SCSI with block.

The block layer SG_IO ioctl passes through the SCSI
command set to a device that understands it
(i.e. not necessarily a "SCSI" device in the traditional
sense). Other pass throughs exist (or may be needed) for
ATA's task file interface and SAS's management protocol.

Even though my tests, shown earlier in this thread, indicated
that the SG_IO ioctl might be a shade faster than O_DIRECT,
the main reason for having it is to pass through "non-block"
commands to a device. Some examples:
- special writes (e.g. formating a disk, writing a CD/DVD)
- uploading firmware
- reading the defect table from a disk
- reading and writing special areas on a disk
(e.g. application client log page)

The reason for choosing this list is that all these
operations potentially move large amounts of data in a
single operation. For such data transfers to be constrained
by max_sectors is questionable. Putting a block paradigm
bypass in the block layer is an interesting design :-)

With these patches in place cdrecord (in RH 9) works via
/dev/hdb (using ide-cd). Cdrecord fails on the same ATAPI
writer via /dev/scd0 because ide-scsi does not set max_sectors
high enough [and the SG_SET_RESERVED_SIZE ioctl reacts
differently in this case to the sg driver].

In summary, I see no reason to constrain the SG_IO ioctl
by max_sectors. SG_IO is a "one shot" with no command
merging or retries. If the HBA driver doesn't like a command,
then it can reject it. [However, currently there is no
mechanism to convey host or HBA driver errors back through
the request queue, only the device (response) status.]

Doug Gilbert


2003-06-02 07:14:35

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Sun, Jun 01 2003, Douglas Gilbert wrote:
> Jens Axboe wrote:
> >On Sat, May 31 2003, Douglas Gilbert wrote:
>
> >>With the latest changes from Jens (mainly dropping the
> >>artificial 64 KB per operation limit) the maximum
> >>element size in the block layer SG_IO is:
> >> - 128 KB when direct I/O is not used (i.e. the user
> >> space buffer does not meet bio_map_user()'s
> >> requirements). This seems to be the largest buffer
> >> kmalloc() will allow (in my tests)
> >
> >
> >Correct.
> >
> >
> >> - (sg_tablesize * page_size) when direct I/O is used.
> >> My test was with the sym53c8xx_2 driver in which
> >> sg_tablesize==96 so my largest element size was 384 KB
> >
> >
> >Or ->max_sectors << 9, whichever is smallest. Really, the limits are in
> >the queue. Don't confuse SCSI with block.
>
> The block layer SG_IO ioctl passes through the SCSI
> command set to a device that understands it
> (i.e. not necessarily a "SCSI" device in the traditional
> sense). Other pass throughs exist (or may be needed) for
> ATA's task file interface and SAS's management protocol.
>
> Even though my tests, shown earlier in this thread, indicated
> that the SG_IO ioctl might be a shade faster than O_DIRECT,
> the main reason for having it is to pass through "non-block"
> commands to a device. Some examples:
> - special writes (e.g. formating a disk, writing a CD/DVD)
> - uploading firmware
> - reading the defect table from a disk
> - reading and writing special areas on a disk
> (e.g. application client log page)
>
> The reason for choosing this list is that all these
> operations potentially move large amounts of data in a
> single operation. For such data transfers to be constrained
> by max_sectors is questionable. Putting a block paradigm
> bypass in the block layer is an interesting design :-)

I think this is nonsense. The block layer will not accept commands
that it cannot handle in one go, what would the point of that be?
There's no way for us to break down a single command into pieces,
we have no idea how to do that. max_sectors _is_ the natural
constraint, it's the hardware limit not something I impose through
policy. For SCSI it could be bigger in some cases, that's up to the
lldd to set though.

> With these patches in place cdrecord (in RH 9) works via
> /dev/hdb (using ide-cd). Cdrecord fails on the same ATAPI
> writer via /dev/scd0 because ide-scsi does not set max_sectors
> high enough [and the SG_SET_RESERVED_SIZE ioctl reacts
> differently in this case to the sg driver].

ide-scsi bug.

> In summary, I see no reason to constrain the SG_IO ioctl
> by max_sectors. SG_IO is a "one shot" with no command
> merging or retries. If the HBA driver doesn't like a command,
> then it can reject it. [However, currently there is no
> mechanism to convey host or HBA driver errors back through
> the request queue, only the device (response) status.]

It breaks existing applications too, which is at least a very
good reason in my book. I think your position is naive. The
driver explicitly asked not to get request bigger than a certain
size, and know you want to rely on the correct handling of that
case? Won't happen.

BTW, if you want me to read emails somewhat reliably, cc me.

Jens

2003-06-03 05:11:02

by Douglas Gilbert

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

Jens Axboe wrote:
> On Sun, Jun 01 2003, Douglas Gilbert wrote:
<snip>
>>The block layer SG_IO ioctl passes through the SCSI
>>command set to a device that understands it
>>(i.e. not necessarily a "SCSI" device in the traditional
>>sense). Other pass throughs exist (or may be needed) for
>>ATA's task file interface and SAS's management protocol.
>>
>>Even though my tests, shown earlier in this thread, indicated
>>that the SG_IO ioctl might be a shade faster than O_DIRECT,
>>the main reason for having it is to pass through "non-block"
>>commands to a device. Some examples:
>> - special writes (e.g. formating a disk, writing a CD/DVD)
>> - uploading firmware
>> - reading the defect table from a disk
>> - reading and writing special areas on a disk
>> (e.g. application client log page)
>>
>>The reason for choosing this list is that all these
>>operations potentially move large amounts of data in a
>>single operation. For such data transfers to be constrained
>>by max_sectors is questionable. Putting a block paradigm
>>bypass in the block layer is an interesting design :-)
>
>
> I think this is nonsense. The block layer will not accept commands
> that it cannot handle in one go, what would the point of that be?
> There's no way for us to break down a single command into pieces,
> we have no idea how to do that. max_sectors _is_ the natural
> constraint, it's the hardware limit not something I impose through
> policy. For SCSI it could be bigger in some cases, that's up to the
> lldd to set though.
<snip>

Jens,
Reviewing the linix-scsi archives, max_sectors was
introduced around lk 2.4.7 and you were quite active
in its promotion. There are also posts about problems
with qlogic HBAs and their need for a limit to maximum
transfer length. So there is some hardware justification.

On 11th April 2002 Justin Gibbs posted this in a mail
about aic7xxx version 6.2.6:
"2) Set max_sectors to a sane value. The aic7xxx driver was not
updated when this value was added to the host template structure.
In more recent kernels, the default setting for this field, 255,
can limit our transaction size to 127K. This often causes the
scsi_merge routines to generate 127k followed by 1k I/Os to complete
a client transaction. The command overhead of such small
transactions
can severely impact performance. The driver now sets max_sectors to
8192 which equates to the 16MB S/G element limit for these cards as
expressed in 2K sectors."

At the time max_sectors defaulted to 255, later it was
bumped to 256 and is now 1024 in lk 2.5. However Justin's
post is saying the hardware limit for a data transfer
associated with a single SCSI command in the aic7xxx
driver is:
sg_tablesize * (2 ** 24) bytes == 2 GB
as the aic7xxx driver sets sg_tablesize to 128.
Taking into account the largest practical kmalloc of 128 KB
(which is not a hardware limitation) this number comes down
to 16 MB. The 8192 figure that Justin chose is still in place
in the aic7xxx driver in lk 2.5 and it limits maximum transfer
size to 4 MB since the unit of max_sectors is now 512 bytes.

Various projects have reported to me success in transferring
8 and 16 MB individual WRITE commands through the sg driver,
usually with LSI or Adaptec HBAs. The max_sectors==8192
set by the aic7xxx is the maximum of any driver in the
ide or the scsi subsystems (both in lk 2.4 and lk 2.5)
currently. Most drivers are picking up the default value.
The definition of "max_sectors" states in
drivers/scsi/hosts.h:
"if the host adapter has limitations beside segment count"
That could be taken to imply if a LLD does not define
max_sectors then there is no limit.

In summary, from a HBA drivers point of view, "max_sectors"
is misnamed (since they transfer bytes) and not precise
enough to describe any limitations on data transfers they
may have.

Apologies in advance for propagating further nonsense.

Doug Gilbert


2003-06-03 06:41:11

by Nick Piggin

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Tue, Jun 03, 2003 at 03:23:19PM +1000, Douglas Gilbert wrote:
> Jens Axboe wrote:
> >On Sun, Jun 01 2003, Douglas Gilbert wrote:
> <snip>
> >>The block layer SG_IO ioctl passes through the SCSI
> >>command set to a device that understands it
> >>(i.e. not necessarily a "SCSI" device in the traditional
> >>sense). Other pass throughs exist (or may be needed) for
> >>ATA's task file interface and SAS's management protocol.
> >>
> >>Even though my tests, shown earlier in this thread, indicated
> >>that the SG_IO ioctl might be a shade faster than O_DIRECT,
> >>the main reason for having it is to pass through "non-block"
> >>commands to a device. Some examples:
> >> - special writes (e.g. formating a disk, writing a CD/DVD)
> >> - uploading firmware
> >> - reading the defect table from a disk
> >> - reading and writing special areas on a disk
> >> (e.g. application client log page)
> >>
> >>The reason for choosing this list is that all these
> >>operations potentially move large amounts of data in a
> >>single operation. For such data transfers to be constrained
> >>by max_sectors is questionable. Putting a block paradigm
> >>bypass in the block layer is an interesting design :-)
> >
> >
> >I think this is nonsense. The block layer will not accept commands
> >that it cannot handle in one go, what would the point of that be?
> >There's no way for us to break down a single command into pieces,
> >we have no idea how to do that. max_sectors _is_ the natural
> >constraint, it's the hardware limit not something I impose through
> >policy. For SCSI it could be bigger in some cases, that's up to the
> >lldd to set though.
> <snip>
>
> Jens,
> Reviewing the linix-scsi archives, max_sectors was
> introduced around lk 2.4.7 and you were quite active
> in its promotion. There are also posts about problems
> with qlogic HBAs and their need for a limit to maximum
> transfer length. So there is some hardware justification.
>
> On 11th April 2002 Justin Gibbs posted this in a mail
> about aic7xxx version 6.2.6:
> "2) Set max_sectors to a sane value. The aic7xxx driver was not
> updated when this value was added to the host template structure.
> In more recent kernels, the default setting for this field, 255,
> can limit our transaction size to 127K. This often causes the
> scsi_merge routines to generate 127k followed by 1k I/Os to complete
> a client transaction. The command overhead of such small
> transactions
> can severely impact performance. The driver now sets max_sectors to
> 8192 which equates to the 16MB S/G element limit for these cards as
> expressed in 2K sectors."
>
> At the time max_sectors defaulted to 255, later it was
> bumped to 256 and is now 1024 in lk 2.5. However Justin's
> post is saying the hardware limit for a data transfer
> associated with a single SCSI command in the aic7xxx
> driver is:
> sg_tablesize * (2 ** 24) bytes == 2 GB
> as the aic7xxx driver sets sg_tablesize to 128.
> Taking into account the largest practical kmalloc of 128 KB
> (which is not a hardware limitation) this number comes down
> to 16 MB. The 8192 figure that Justin chose is still in place
> in the aic7xxx driver in lk 2.5 and it limits maximum transfer
> size to 4 MB since the unit of max_sectors is now 512 bytes.
>
> Various projects have reported to me success in transferring
> 8 and 16 MB individual WRITE commands through the sg driver,
> usually with LSI or Adaptec HBAs. The max_sectors==8192
> set by the aic7xxx is the maximum of any driver in the
> ide or the scsi subsystems (both in lk 2.4 and lk 2.5)
> currently.

I would just like to add my 2c here, and say that 16MB
requests are just a bit too big for a general purpose
installation, and using any of the available IO schedulers.

The grainularity and disparity between large and small
requests is just too large. I know AS wouldn't cope well
with requests that large in a general purpose situation
(general purpose being < 4000 disks :P )

I would be really interested in seeing benchmarks which
showed a significant performance improvement when going
from say 128K requests to say 16MB. Even in the most
favourable conditions for big request sizes, I'd say
128K should be getting toward the point of diminishing
returns.

Nick

2003-06-03 08:16:54

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] SG_IO readcd and various bugs

On Tue, Jun 03 2003, Douglas Gilbert wrote:
> Jens Axboe wrote:
> >On Sun, Jun 01 2003, Douglas Gilbert wrote:
> <snip>
> >>The block layer SG_IO ioctl passes through the SCSI
> >>command set to a device that understands it
> >>(i.e. not necessarily a "SCSI" device in the traditional
> >>sense). Other pass throughs exist (or may be needed) for
> >>ATA's task file interface and SAS's management protocol.
> >>
> >>Even though my tests, shown earlier in this thread, indicated
> >>that the SG_IO ioctl might be a shade faster than O_DIRECT,
> >>the main reason for having it is to pass through "non-block"
> >>commands to a device. Some examples:
> >> - special writes (e.g. formating a disk, writing a CD/DVD)
> >> - uploading firmware
> >> - reading the defect table from a disk
> >> - reading and writing special areas on a disk
> >> (e.g. application client log page)
> >>
> >>The reason for choosing this list is that all these
> >>operations potentially move large amounts of data in a
> >>single operation. For such data transfers to be constrained
> >>by max_sectors is questionable. Putting a block paradigm
> >>bypass in the block layer is an interesting design :-)
> >
> >
> >I think this is nonsense. The block layer will not accept commands
> >that it cannot handle in one go, what would the point of that be?
> >There's no way for us to break down a single command into pieces,
> >we have no idea how to do that. max_sectors _is_ the natural
> >constraint, it's the hardware limit not something I impose through
> >policy. For SCSI it could be bigger in some cases, that's up to the
> >lldd to set though.
> <snip>
>
> Jens,
> Reviewing the linix-scsi archives, max_sectors was
> introduced around lk 2.4.7 and you were quite active
> in its promotion. There are also posts about problems
> with qlogic HBAs and their need for a limit to maximum
> transfer length. So there is some hardware justification.
>
> On 11th April 2002 Justin Gibbs posted this in a mail
> about aic7xxx version 6.2.6:
> "2) Set max_sectors to a sane value. The aic7xxx driver was not
> updated when this value was added to the host template structure.
> In more recent kernels, the default setting for this field, 255,
> can limit our transaction size to 127K. This often causes the
> scsi_merge routines to generate 127k followed by 1k I/Os to complete
> a client transaction. The command overhead of such small
> transactions
> can severely impact performance. The driver now sets max_sectors to
> 8192 which equates to the 16MB S/G element limit for these cards as
> expressed in 2K sectors."
>
> At the time max_sectors defaulted to 255, later it was
> bumped to 256 and is now 1024 in lk 2.5. However Justin's
> post is saying the hardware limit for a data transfer
> associated with a single SCSI command in the aic7xxx
> driver is:
> sg_tablesize * (2 ** 24) bytes == 2 GB
> as the aic7xxx driver sets sg_tablesize to 128.
> Taking into account the largest practical kmalloc of 128 KB
> (which is not a hardware limitation) this number comes down
> to 16 MB. The 8192 figure that Justin chose is still in place
> in the aic7xxx driver in lk 2.5 and it limits maximum transfer
> size to 4 MB since the unit of max_sectors is now 512 bytes.
>
> Various projects have reported to me success in transferring
> 8 and 16 MB individual WRITE commands through the sg driver,
> usually with LSI or Adaptec HBAs. The max_sectors==8192
> set by the aic7xxx is the maximum of any driver in the
> ide or the scsi subsystems (both in lk 2.4 and lk 2.5)
> currently. Most drivers are picking up the default value.
> The definition of "max_sectors" states in
> drivers/scsi/hosts.h:
> "if the host adapter has limitations beside segment count"
> That could be taken to imply if a LLD does not define
> max_sectors then there is no limit.
>
> In summary, from a HBA drivers point of view, "max_sectors"
> is misnamed (since they transfer bytes) and not precise
> enough to describe any limitations on data transfers they
> may have.
>
> Apologies in advance for propagating further nonsense.

Wow, that was a long email. I don't have good connectivity these days,
so mail collisions are bound to happen.

As I wrote in the last email to you, it might make sense to introduce a
hard upper limit and a preferred limit. I think you are missing the
point with the latency requirements. If you allow 16MB sg requests in
the queue, you will both have pinned down a _lot_ of memory (that's one
problem) and build up a huge latency queue. And that's not even
considering that it makes _no_ sense from a performance pov to go as
high as 16MB, zero.

The fact is that for some drivers, max_sectors is a hard limit. There's
no way that scsi_ioctl will pass down requests bigger than this, period.
If 512KB is too small for some operations (your firmware case, it makes
sense), then I'm all for fixing that up.

--
Jens Axboe