Commit 4b0991ad authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-scsi.bkbits.net/scsi-bugfixes-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents d1d8f3b6 e2d02589
...@@ -124,6 +124,8 @@ static int sg_set_reserved_size(request_queue_t *q, int *p) ...@@ -124,6 +124,8 @@ static int sg_set_reserved_size(request_queue_t *q, int *p)
if (err) if (err)
return err; return err;
if (size < 0)
return -EINVAL;
if (size > (q->max_sectors << 9)) if (size > (q->max_sectors << 9))
return -EINVAL; return -EINVAL;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1) #define AAC_MAX_TARGET (MAXIMUM_NUM_CONTAINERS+1)
#define AAC_MAX_LUN (8) #define AAC_MAX_LUN (8)
#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
/* /*
* These macros convert from physical channels to virtual channels * These macros convert from physical channels to virtual channels
*/ */
......
...@@ -92,7 +92,21 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co ...@@ -92,7 +92,21 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize); init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
init->HostPhysMemPages = cpu_to_le32(num_physpages); // number of 4k pages of host physical memory /*
* number of 4k pages of host physical memory. The aacraid fw needs
* this number to be less than 4gb worth of pages. num_physpages is in
* system page units. New firmware doesn't have any issues with the
* mapping system, but older Firmware did, and had *troubles* dealing
* with the math overloading past 32 bits, thus we must limit this
* field.
*/
if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) {
init->HostPhysMemPages =
cpu_to_le32(num_physpages << (PAGE_SHIFT-12));
} else {
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
}
/* /*
* Increment the base address by the amount already used * Increment the base address by the amount already used
......
...@@ -64,40 +64,52 @@ static const char *group_1_commands[] = { ...@@ -64,40 +64,52 @@ static const char *group_1_commands[] = {
static const char *group_2_commands[] = { static const char *group_2_commands[] = {
/* 40-41 */ "Change Definition", "Write Same", /* 40-41 */ "Change Definition", "Write Same",
/* 42-48 */ "Read sub-channel", "Read TOC", "Read header", /* 42-48 */ "Read sub-channel", "Read TOC", "Read header",
"Play audio (10)", unknown, "Play audio msf", "Play audio (10)", "Get configuration", "Play audio msf",
"Play audio track/index", "Play audio track/index",
/* 49-4f */ "Play track relative (10)", unknown, "Pause/resume", /* 49-4f */ "Play track relative (10)", "Get event status notification",
"Log Select", "Log Sense", unknown, unknown, "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
/* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)", unknown,
/* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown, /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info",
/* 5c-5f */ unknown, unknown, unknown, "Reserve track", "Send OPC onfo", "Mode Select (10)",
/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue",
"Mode Sense (10)", "Close track/session",
/* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in",
"Persistent reserve out",
}; };
/* The following are 16 byte commands in group 4 */ /* The following are 16 byte commands in group 4 */
static const char *group_4_commands[] = { static const char *group_4_commands[] = {
/* 80-84 */ unknown, unknown, unknown, unknown, unknown, /* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy",
/* 85-89 */ "Memory Export In (16)", unknown, unknown, unknown, "Receive copy results",
"Memory Export Out (16)", /* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out",
/* 8a-8f */ unknown, unknown, unknown, unknown, unknown, unknown, "Read (16)", "Memory Export Out (16)",
/* 90-94 */ unknown, unknown, unknown, unknown, unknown, /* 8a-8f */ "Write (16)", unknown, "Read attributes", "Write attributes",
"Write and verify (16)", "Verify (16)",
/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)",
"Lock/unlock cache (16)", "Write same (16)", unknown,
/* 95-99 */ unknown, unknown, unknown, unknown, unknown, /* 95-99 */ unknown, unknown, unknown, unknown, unknown,
/* 9a-9f */ unknown, unknown, unknown, unknown, unknown, unknown, /* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in",
"Service action out",
}; };
/* The following are 12 byte commands in group 5 */ /* The following are 12 byte commands in group 5 */
static const char *group_5_commands[] = { static const char *group_5_commands[] = {
/* a0-a5 */ unknown, unknown, unknown, unknown, unknown, /* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)",
"Move medium/play audio(12)", "Maintenance (out)", "Move medium/play audio(12)",
/* a6-a9 */ "Exchange medium", unknown, "Read(12)", "Play track relative(12)", /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)",
/* aa-ae */ "Write(12)", unknown, "Erase(12)", unknown, "Play track relative(12)",
"Write and verify(12)", /* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance",
"Read DVD structure", "Write and verify(12)",
/* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)",
/* b2-b4 */ "Search data low(12)", "Set limits(12)", unknown, /* b2-b4 */ "Search data low(12)", "Set limits(12)",
/* b5-b6 */ "Request volume element address", "Send volume tag", "Read element status attached",
/* b7-b9 */ "Read defect data(12)", "Read element status", unknown, /* b5-b6 */ "Request volume element address", "Send volume tag, set streaming",
/* ba-bf */ unknown, unknown, unknown, unknown, unknown, unknown, /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf",
/* ba-bc */ "Redundancy group (in), Scan",
"Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd",
/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd",
"Volume set (out), Send DVD structure",
}; };
......
...@@ -914,9 +914,7 @@ void scsi_device_put(struct scsi_device *sdev) ...@@ -914,9 +914,7 @@ void scsi_device_put(struct scsi_device *sdev)
return; return;
module_put(sdev->host->hostt->module); module_put(sdev->host->hostt->module);
if (atomic_dec_and_test(&sdev->access_count)) atomic_dec(&sdev->access_count);
if (test_bit(SDEV_DEL, &sdev->sdev_state))
device_del(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev); put_device(&sdev->sdev_gendev);
class_put(&sdev_class); class_put(&sdev_class);
} }
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <scsi/scsi_devinfo.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h" #include "scsi_priv.h"
#include "scsi_devinfo.h"
/* /*
* scsi_dev_info_list: structure to hold black/white listed devices. * scsi_dev_info_list: structure to hold black/white listed devices.
...@@ -322,11 +323,17 @@ static int scsi_dev_info_list_add_str(char *dev_list) ...@@ -322,11 +323,17 @@ static int scsi_dev_info_list_add_str(char *dev_list)
* Description: * Description:
* Search the scsi_dev_info_list for an entry matching @vendor and * Search the scsi_dev_info_list for an entry matching @vendor and
* @model, if found, return the matching flags value, else return * @model, if found, return the matching flags value, else return
* scsi_default_dev_flags. * the host or global default settings.
**/ **/
int scsi_get_device_flags(unsigned char *vendor, unsigned char *model) int scsi_get_device_flags(struct scsi_device *sdev, unsigned char *vendor,
unsigned char *model)
{ {
struct scsi_dev_info_list *devinfo; struct scsi_dev_info_list *devinfo;
unsigned int bflags;
bflags = sdev->host->hostt->flags;
if (!bflags)
bflags = scsi_default_dev_flags;
list_for_each_entry(devinfo, &scsi_dev_info_list, dev_info_list) { list_for_each_entry(devinfo, &scsi_dev_info_list, dev_info_list) {
if (devinfo->compatible) { if (devinfo->compatible) {
...@@ -378,7 +385,7 @@ int scsi_get_device_flags(unsigned char *vendor, unsigned char *model) ...@@ -378,7 +385,7 @@ int scsi_get_device_flags(unsigned char *vendor, unsigned char *model)
return devinfo->flags; return devinfo->flags;
} }
} }
return scsi_default_dev_flags; return bflags;
} }
#ifdef CONFIG_SCSI_PROC_FS #ifdef CONFIG_SCSI_PROC_FS
......
...@@ -85,7 +85,8 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, ...@@ -85,7 +85,8 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
extern void __scsi_release_request(struct scsi_request *sreq); extern void __scsi_release_request(struct scsi_request *sreq);
/* scsi_devinfo.c */ /* scsi_devinfo.c */
extern int scsi_get_device_flags(unsigned char *vendor, unsigned char *model); extern int scsi_get_device_flags(struct scsi_device *sdev,
unsigned char *vendor, unsigned char *model);
extern int scsi_init_devinfo(void); extern int scsi_init_devinfo(void);
extern void scsi_exit_devinfo(void); extern void scsi_exit_devinfo(void);
......
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_driver.h> #include <scsi/scsi_driver.h>
#include <scsi/scsi_devinfo.h>
#include "scsi_priv.h" #include "scsi_priv.h"
#include "scsi_logging.h" #include "scsi_logging.h"
#include "scsi_devinfo.h"
#define ALLOC_FAILURE_MSG KERN_ERR "%s: Allocation failure during" \ #define ALLOC_FAILURE_MSG KERN_ERR "%s: Allocation failure during" \
" SCSI scanning, some SCSI devices might not be configured\n" " SCSI scanning, some SCSI devices might not be configured\n"
...@@ -365,7 +365,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, ...@@ -365,7 +365,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
* bit fields in Scsi_Device, so bflags need not be passed as an * bit fields in Scsi_Device, so bflags need not be passed as an
* argument. * argument.
*/ */
*bflags |= scsi_get_device_flags(&inq_result[8], &inq_result[16]); *bflags |= scsi_get_device_flags(sdev, &inq_result[8], &inq_result[16]);
possible_inq_resp_len = (unsigned char) inq_result[4] + 5; possible_inq_resp_len = (unsigned char) inq_result[4] + 5;
if (BLIST_INQUIRY_36 & *bflags) if (BLIST_INQUIRY_36 & *bflags)
...@@ -625,7 +625,15 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) ...@@ -625,7 +625,15 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED; sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
sdev->use_10_for_rw = 1; sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 0;
if (*bflags & BLIST_MS_SKIP_PAGE_08)
sdev->skip_ms_page_8 = 1;
if (*bflags & BLIST_MS_SKIP_PAGE_3F)
sdev->skip_ms_page_3f = 1;
if (*bflags & BLIST_USE_10_BYTE_MS)
sdev->use_10_for_ms = 1;
if(sdev->host->hostt->slave_configure) if(sdev->host->hostt->slave_configure)
sdev->host->hostt->slave_configure(sdev); sdev->host->hostt->slave_configure(sdev);
...@@ -678,7 +686,8 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host, ...@@ -678,7 +686,8 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
if (sdevp) if (sdevp)
*sdevp = sdev; *sdevp = sdev;
if (bflagsp) if (bflagsp)
*bflagsp = scsi_get_device_flags(sdev->vendor, *bflagsp = scsi_get_device_flags(sdev,
sdev->vendor,
sdev->model); sdev->model);
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
...@@ -1080,8 +1089,12 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost, ...@@ -1080,8 +1089,12 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
void scsi_rescan_device(struct device *dev) void scsi_rescan_device(struct device *dev)
{ {
struct scsi_driver *drv = to_scsi_driver(dev->driver); struct scsi_driver *drv;
if (!dev->driver)
return;
drv = to_scsi_driver(dev->driver);
if (try_module_get(drv->owner)) { if (try_module_get(drv->owner)) {
if (drv->rescan) if (drv->rescan)
drv->rescan(dev); drv->rescan(dev);
......
...@@ -412,7 +412,6 @@ void scsi_remove_device(struct scsi_device *sdev) ...@@ -412,7 +412,6 @@ void scsi_remove_device(struct scsi_device *sdev)
set_bit(SDEV_DEL, &sdev->sdev_state); set_bit(SDEV_DEL, &sdev->sdev_state);
if (sdev->host->hostt->slave_destroy) if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev); sdev->host->hostt->slave_destroy(sdev);
if (!atomic_read(&sdev->access_count))
device_del(&sdev->sdev_gendev); device_del(&sdev->sdev_gendev);
up_write(&class->subsys.rwsem); up_write(&class->subsys.rwsem);
} }
......
...@@ -74,9 +74,16 @@ ...@@ -74,9 +74,16 @@
*/ */
#define SD_MAX_RETRIES 5 #define SD_MAX_RETRIES 5
static void scsi_disk_release (struct kobject *kobj);
static struct kobj_type scsi_disk_kobj_type = {
.release = scsi_disk_release,
};
struct scsi_disk { struct scsi_disk {
struct scsi_driver *driver; /* always &sd_template */ struct scsi_driver *driver; /* always &sd_template */
struct scsi_device *device; struct scsi_device *device;
struct kobject kobj;
struct gendisk *disk; struct gendisk *disk;
unsigned int openers; /* protected by BKL for now, yuck */ unsigned int openers; /* protected by BKL for now, yuck */
sector_t capacity; /* size in 512-byte sectors */ sector_t capacity; /* size in 512-byte sectors */
...@@ -87,6 +94,7 @@ struct scsi_disk { ...@@ -87,6 +94,7 @@ struct scsi_disk {
unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned RCD : 1; /* state of disk RCD bit, unused */
}; };
static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG]; static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED; static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
...@@ -128,11 +136,33 @@ static int sd_major(int major_idx) ...@@ -128,11 +136,33 @@ static int sd_major(int major_idx)
} }
} }
#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,kobj);
static inline struct scsi_disk *scsi_disk(struct gendisk *disk) static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
{ {
return container_of(disk->private_data, struct scsi_disk, driver); return container_of(disk->private_data, struct scsi_disk, driver);
} }
static int scsi_disk_get(struct scsi_disk *sdkp)
{
if (!kobject_get(&sdkp->kobj))
goto out;
if (scsi_device_get(sdkp->device))
goto out_put_kobj;
return 0;
out_put_kobj:
kobject_put(&sdkp->kobj);
out:
return -ENXIO;
}
static void scsi_disk_put(struct scsi_disk *sdkp)
{
scsi_device_put(sdkp->device);
kobject_put(&sdkp->kobj);
}
/** /**
* sd_init_command - build a scsi (read or write) command from * sd_init_command - build a scsi (read or write) command from
* information in the request structure. * information in the request structure.
...@@ -352,15 +382,17 @@ static int sd_open(struct inode *inode, struct file *filp) ...@@ -352,15 +382,17 @@ static int sd_open(struct inode *inode, struct file *filp)
{ {
struct gendisk *disk = inode->i_bdev->bd_disk; struct gendisk *disk = inode->i_bdev->bd_disk;
struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_disk *sdkp = scsi_disk(disk);
struct scsi_device *sdev = sdkp->device; struct scsi_device *sdev;
int retval; int retval;
SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name)); SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name));
retval = scsi_device_get(sdev); retval = scsi_disk_get(sdkp);
if (retval) if (retval)
return retval; return retval;
sdev = sdkp->device;
/* /*
* If the device is in error recovery, wait until it is done. * If the device is in error recovery, wait until it is done.
* If the device is offline, then disallow any access to it. * If the device is offline, then disallow any access to it.
...@@ -406,7 +438,7 @@ static int sd_open(struct inode *inode, struct file *filp) ...@@ -406,7 +438,7 @@ static int sd_open(struct inode *inode, struct file *filp)
return 0; return 0;
error_out: error_out:
scsi_device_put(sdev); scsi_disk_put(sdkp);
return retval; return retval;
} }
...@@ -438,7 +470,7 @@ static int sd_release(struct inode *inode, struct file *filp) ...@@ -438,7 +470,7 @@ static int sd_release(struct inode *inode, struct file *filp)
* XXX and what if there are packets in flight and this close() * XXX and what if there are packets in flight and this close()
* XXX is followed by a "rmmod sd_mod"? * XXX is followed by a "rmmod sd_mod"?
*/ */
scsi_device_put(sdev); scsi_disk_put(sdkp);
return 0; return 0;
} }
...@@ -1057,6 +1089,11 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, ...@@ -1057,6 +1089,11 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
int res; int res;
struct scsi_mode_data data; struct scsi_mode_data data;
if (sdkp->device->skip_ms_page_3f) {
printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname);
return;
}
/* /*
* First attempt: ask for all pages (0x3F), but only 4 bytes. * First attempt: ask for all pages (0x3F), but only 4 bytes.
* We have to start carefully: some devices hang if we ask * We have to start carefully: some devices hang if we ask
...@@ -1103,6 +1140,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1103,6 +1140,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
const int modepage = 0x08; /* current values, cache page */ const int modepage = 0x08; /* current values, cache page */
struct scsi_mode_data data; struct scsi_mode_data data;
if (sdkp->device->skip_ms_page_8)
goto defaults;
/* cautiously ask */ /* cautiously ask */
res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data); res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
...@@ -1160,6 +1199,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ...@@ -1160,6 +1199,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
printk(KERN_ERR "%s: asking for cache data failed\n", printk(KERN_ERR "%s: asking for cache data failed\n",
diskname); diskname);
} }
defaults:
printk(KERN_ERR "%s: assuming drive cache: write through\n", printk(KERN_ERR "%s: assuming drive cache: write through\n",
diskname); diskname);
sdkp->WCE = 0; sdkp->WCE = 0;
...@@ -1270,6 +1311,10 @@ static int sd_probe(struct device *dev) ...@@ -1270,6 +1311,10 @@ static int sd_probe(struct device *dev)
if (!sdkp) if (!sdkp)
goto out; goto out;
memset (sdkp, 0, sizeof(*sdkp));
kobject_init(&sdkp->kobj);
sdkp->kobj.ktype = &scsi_disk_kobj_type;
gd = alloc_disk(16); gd = alloc_disk(16);
if (!gd) if (!gd)
goto out_free; goto out_free;
...@@ -1348,16 +1393,27 @@ static int sd_remove(struct device *dev) ...@@ -1348,16 +1393,27 @@ static int sd_remove(struct device *dev)
struct scsi_disk *sdkp = dev_get_drvdata(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev);
del_gendisk(sdkp->disk); del_gendisk(sdkp->disk);
sd_shutdown(dev);
kobject_put(&sdkp->kobj);
return 0;
}
/**
* scsi_disk_release - Called to free the scsi_disk structure
* @kobj: pointer to embedded kobject
**/
static void scsi_disk_release(struct kobject *kobj)
{
struct scsi_disk *sdkp = to_scsi_disk(kobj);
put_disk(sdkp->disk);
spin_lock(&sd_index_lock); spin_lock(&sd_index_lock);
clear_bit(sdkp->index, sd_index_bits); clear_bit(sdkp->index, sd_index_bits);
spin_unlock(&sd_index_lock); spin_unlock(&sd_index_lock);
sd_shutdown(dev);
put_disk(sdkp->disk);
kfree(sdkp); kfree(sdkp);
return 0;
} }
/* /*
......
...@@ -877,6 +877,8 @@ sg_ioctl(struct inode *inode, struct file *filp, ...@@ -877,6 +877,8 @@ sg_ioctl(struct inode *inode, struct file *filp,
result = get_user(val, (int *) arg); result = get_user(val, (int *) arg);
if (result) if (result)
return result; return result;
if (val < 0)
return -EINVAL;
if (val != sfp->reserve.bufflen) { if (val != sfp->reserve.bufflen) {
if (sg_res_in_use(sfp) || sfp->mmap_called) if (sg_res_in_use(sfp) || sfp->mmap_called)
return -EBUSY; return -EBUSY;
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <scsi/scsi_devinfo.h>
/*********************************************************************** /***********************************************************************
...@@ -64,10 +65,6 @@ static const char* host_info(struct Scsi_Host *host) ...@@ -64,10 +65,6 @@ static const char* host_info(struct Scsi_Host *host)
static int slave_configure (struct scsi_device *sdev) static int slave_configure (struct scsi_device *sdev)
{ {
/* set device to use 10-byte commands where possible */
sdev->use_10_for_ms = 1;
sdev->use_10_for_rw = 1;
/* this is to satisify the compiler, tho I don't think the /* this is to satisify the compiler, tho I don't think the
* return code is ever checked anywhere. */ * return code is ever checked anywhere. */
return 0; return 0;
...@@ -324,6 +321,9 @@ struct scsi_host_template usb_stor_host_template = { ...@@ -324,6 +321,9 @@ struct scsi_host_template usb_stor_host_template = {
/* emulated HBA */ /* emulated HBA */
.emulated = TRUE, .emulated = TRUE,
/* modify scsi_device bits on probe */
.flags = (BLIST_MS_SKIP_PAGE_08 | BLIST_USE_10_BYTE_MS),
/* module management */ /* module management */
.module = THIS_MODULE .module = THIS_MODULE
}; };
......
...@@ -86,6 +86,8 @@ struct scsi_device { ...@@ -86,6 +86,8 @@ struct scsi_device {
* because we did a bus reset. */ * because we did a bus reset. */
unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */
unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */
unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */
unsigned no_start_on_add:1; /* do not issue start on add */ unsigned no_start_on_add:1; /* do not issue start on add */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */ unsigned int device_blocked; /* Device returned QUEUE_FULL. */
......
#ifndef _SCSI_SCSI_DEVINFO_H
#define _SCSI_SCSI_DEVINFO_H
/* /*
* Flags for SCSI devices that need special treatment * Flags for SCSI devices that need special treatment
*/ */
...@@ -15,3 +16,7 @@ ...@@ -15,3 +16,7 @@
#define BLIST_INQUIRY_36 0x400 /* override additional length field */ #define BLIST_INQUIRY_36 0x400 /* override additional length field */
#define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */ #define BLIST_INQUIRY_58 0x800 /* ... for broken inquiry responses */
#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */ #define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */
#define BLIST_MS_SKIP_PAGE_08 0x2000 /* do not send ms page 0x08 */
#define BLIST_MS_SKIP_PAGE_3F 0x4000 /* do not send ms page 0x3f */
#define BLIST_USE_10_BYTE_MS 0x8000 /* use 10 byte ms before 6 byte ms */
#endif
...@@ -344,6 +344,12 @@ struct scsi_host_template { ...@@ -344,6 +344,12 @@ struct scsi_host_template {
* module_init/module_exit. * module_init/module_exit.
*/ */
struct list_head legacy_hosts; struct list_head legacy_hosts;
/*
* Default flags settings, these modify the setting of scsi_device
* bits.
*/
unsigned int flags;
}; };
/* /*
......
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