Commit a19bafa6 authored by Andries E. Brouwer's avatar Andries E. Brouwer Committed by Linus Torvalds

[PATCH] scsi stuff

The patch below cleans up some SCSI stuff.

The main purpose is to avoid trying to read the partition table
of a removable disk when the drive has told us that no media
are present. (Right now we try to read a 4K block and fail and
retry and fail, and give an I/O error on the first sector,
then try to read the second sector and fail and retry ...)

Unused fields  sector_bit_size  and  sector_bit_shift  in
struct scsi_disk were removed. The field  has_part_table
(that has nothing to do with partition tables) was
renamed to  has_been_registered . The field  ready  was
renamed to  media_present .
The overly long  sd_init_onedisk()  was split up.

When we notice that no media are present anymore, the
partitions are removed from /proc/partitions, but the
drive remains, with size 0.

A future patch will remove the field  capacity  - there are
all too many places where capacities are stored - but the
present patch is large enough already.

There is also a quite independent patch in scsi_error.c
(yesterday someone had an infinite loop retrying to read
bad media) - this patch honours the SCpnt->retries.
In case you applied this already, just ignore the scsi_error.c part.

Also some "Overrides for Emacs" were removed.
parent 2b4b6c20
......@@ -177,9 +177,10 @@ static int show_partition(struct seq_file *part, void *v)
if (sgp == gendisk_head)
seq_puts(part, "major minor #blocks name\n\n");
/* show all non-0 size partitions of this disk */
/* show the full disk and all non-0 size partitions of it */
for (n = 0; n < (sgp->nr_real << sgp->minor_shift); n++) {
if (sgp->part[n].nr_sects == 0)
int minormask = (1<<sgp->minor_shift) - 1;
if ((n & minormask) && sgp->part[n].nr_sects == 0)
continue;
seq_printf(part, "%4d %4d %10d %s\n",
sgp->major, n, sgp->sizes[n],
......
......@@ -2048,7 +2048,7 @@ static int esp_do_data_finale(struct NCR_ESP *esp,
* and not only for the entire host adapter as it is now, the workaround
* is way to expensive performance wise.
* Instead, it turns out that when this happens the target has disconnected
* allready but it doesn't show in the interrupt register. Compensate for
* already but it doesn't show in the interrupt register. Compensate for
* that here to try and avoid a SCSI bus reset.
*/
if(!esp->fas_premature_intr_workaround && (fifocnt == 1) &&
......
......@@ -1095,6 +1095,8 @@ int scsi_decide_disposition(Scsi_Cmnd * SCpnt)
*/
STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
{
int rtn;
/*
* First check the host byte, to see if there is anything in there
* that would indicate what we need to do.
......@@ -1102,20 +1104,25 @@ STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
if (host_byte(SCpnt->result) == DID_RESET) {
if (SCpnt->flags & IS_RESETTING) {
/*
* OK, this is normal. We don't know whether in fact the
* command in question really needs to be rerun or not -
* if this was the original data command then the answer is yes,
* otherwise we just flag it as success.
* OK, this is normal. We don't know whether in fact
* the command in question really needs to be rerun
* or not - if this was the original data command then
* the answer is yes, otherwise we just flag it as
* success.
*/
SCpnt->flags &= ~IS_RESETTING;
return NEEDS_RETRY;
goto maybe_retry;
}
/*
* Rats. We are already in the error handler, so we now get to try
* and figure out what to do next. If the sense is valid, we have
* a pretty good idea of what to do. If not, we mark it as failed.
* Rats. We are already in the error handler, so we now
* get to try and figure out what to do next. If the sense
* is valid, we have a pretty good idea of what to do.
* If not, we mark it as failed.
*/
return scsi_check_sense(SCpnt);
rtn = scsi_check_sense(SCpnt);
if (rtn == NEEDS_RETRY)
goto maybe_retry;
return rtn;
}
if (host_byte(SCpnt->result) != DID_OK) {
return FAILED;
......@@ -1127,14 +1134,18 @@ STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
return FAILED;
}
/*
* Now, check the status byte to see if this indicates anything special.
* Now, check the status byte to see if this indicates
* anything special.
*/
switch (status_byte(SCpnt->result)) {
case GOOD:
case COMMAND_TERMINATED:
return SUCCESS;
case CHECK_CONDITION:
return scsi_check_sense(SCpnt);
rtn = scsi_check_sense(SCpnt);
if (rtn == NEEDS_RETRY)
goto maybe_retry;
return rtn;
case CONDITION_GOOD:
case INTERMEDIATE_GOOD:
case INTERMEDIATE_C_GOOD:
......@@ -1149,6 +1160,14 @@ STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
return FAILED;
}
return FAILED;
maybe_retry:
if ((++SCpnt->retries) < SCpnt->allowed) {
return NEEDS_RETRY;
} else {
/* No more retries - report this one back to upper level */
return SUCCESS;
}
}
/*
......
......@@ -127,7 +127,7 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
/* gag this error, VFS will log it anyway /axboe */
/* printk(KERN_INFO "Disc change detected.\n"); */
break;
};
}
default: /* Fall through for non-removable media */
printk("SCSI error: host %d id %d lun %d return code = %x\n",
dev->host->host_no,
......@@ -139,7 +139,7 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
sense_error(SRpnt->sr_sense_buffer[0]),
SRpnt->sr_sense_buffer[2] & 0xf);
};
}
result = SRpnt->sr_result;
......@@ -152,7 +152,7 @@ static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
}
/*
* This interface is depreciated - users should use the scsi generic (sg)
* This interface is deprecated - users should use the scsi generic (sg)
* interface instead, as this is a more flexible approach to performing
* generic SCSI commands on a device.
*
......@@ -516,22 +516,3 @@ int kernel_scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
set_fs(oldfs);
return tmp;
}
/*
* Overrides for Emacs so that we almost follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
This diff is collapsed.
......@@ -11,9 +11,6 @@
*/
#ifndef _SD_H
#define _SD_H
/*
$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
*/
#ifndef _SCSI_H
#include "scsi.h"
......@@ -26,13 +23,11 @@
extern struct hd_struct *sd;
typedef struct scsi_disk {
unsigned capacity; /* size in blocks */
unsigned capacity; /* size in 512-byte sectors */
Scsi_Device *device;
unsigned char ready; /* flag ready for FLOPTICAL */
unsigned char write_prot; /* flag write_protect for rmvable dev */
unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */
unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
unsigned has_part_table:1; /* has partition table */
unsigned char media_present;
unsigned char write_prot;
unsigned has_been_registered:1;
} Scsi_Disk;
extern int revalidate_scsidisk(kdev_t dev, int maxusage);
......@@ -48,22 +43,3 @@ extern kdev_t sd_find_target(void *host, int tgt);
#define SD_PARTITION(i) (((major(i) & SD_MAJOR_MASK) << 8) | (minor(i) & 255))
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
......@@ -24,8 +24,6 @@ typedef struct {
Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
unsigned long ms_offset; /* for reading multisession-CD's */
unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */
unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift */
unsigned needs_sector_size:1; /* needs to get sector size */
unsigned use:1; /* is this device still supportable */
unsigned xa_flag:1; /* CD has XA sectors ? */
......
......@@ -412,8 +412,8 @@ void grok_partitions(kdev_t dev, long size)
g->part[first_minor].nr_sects = size;
/* No such device or no minors to use for partitions */
if (!size || minors == 1)
/* No minors to use for partitions */
if (minors == 1)
return;
if (g->sizes) {
......@@ -422,6 +422,11 @@ void grok_partitions(kdev_t dev, long size)
g->sizes[i] = 0;
}
blk_size[g->major] = g->sizes;
/* No such device (e.g., media were just removed) */
if (!size)
return;
check_partition(g, mk_kdev(g->major, first_minor), 1 + first_minor);
/*
......
......@@ -223,23 +223,4 @@ typedef struct scsi_lun {
/* Used to get the PCI location of a device */
#define SCSI_IOCTL_GET_PCI 0x5387
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment