Commit 63ae7a91 authored by Patrick Mochel's avatar Patrick Mochel

Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
parents 3c8d66aa 621ce5a8
...@@ -130,12 +130,16 @@ ENTRY(lcall7) ...@@ -130,12 +130,16 @@ ENTRY(lcall7)
# gates, which has to be cleaned up later.. # gates, which has to be cleaned up later..
pushl %eax pushl %eax
SAVE_ALL SAVE_ALL
movl EIP(%esp), %eax # due to call gates, this is eflags, not eip.. movl %esp, %ebx
movl CS(%esp), %edx # this is eip.. pushl %ebx
movl EFLAGS(%esp), %ecx # and this is cs.. pushl $0x7
movl %eax,EFLAGS(%esp) # do_lcall:
movl %edx,EIP(%esp) # Now we move them to their "normal" places movl EIP(%ebx), %eax # due to call gates, this is eflags, not eip..
movl %ecx,CS(%esp) # movl CS(%ebx), %edx # this is eip..
movl EFLAGS(%ebx), %ecx # and this is cs..
movl %eax,EFLAGS(%ebx) #
movl %edx,EIP(%ebx) # Now we move them to their "normal" places
movl %ecx,CS(%ebx) #
# #
# Call gates don't clear TF and NT in eflags like # Call gates don't clear TF and NT in eflags like
...@@ -147,13 +151,9 @@ ENTRY(lcall7) ...@@ -147,13 +151,9 @@ ENTRY(lcall7)
pushl %eax pushl %eax
popfl popfl
movl %esp, %ebx
pushl %ebx
andl $-8192, %ebx # GET_THREAD_INFO andl $-8192, %ebx # GET_THREAD_INFO
movl TI_EXEC_DOMAIN(%ebx), %edx # Get the execution domain movl TI_EXEC_DOMAIN(%ebx), %edx # Get the execution domain
movl 4(%edx), %edx # Get the lcall7 handler for the domain call *4(%edx) # Call the lcall7 handler for the domain
pushl $0x7
call *%edx
addl $4, %esp addl $4, %esp
popl %eax popl %eax
jmp resume_userspace jmp resume_userspace
...@@ -163,33 +163,10 @@ ENTRY(lcall27) ...@@ -163,33 +163,10 @@ ENTRY(lcall27)
# gates, which has to be cleaned up later.. # gates, which has to be cleaned up later..
pushl %eax pushl %eax
SAVE_ALL SAVE_ALL
movl EIP(%esp), %eax # due to call gates, this is eflags, not eip..
movl CS(%esp), %edx # this is eip..
movl EFLAGS(%esp), %ecx # and this is cs..
movl %eax,EFLAGS(%esp) #
movl %edx,EIP(%esp) # Now we move them to their "normal" places
movl %ecx,CS(%esp) #
#
# Call gates don't clear TF and NT in eflags like
# traps do, so we need to do it ourselves.
# %eax already contains eflags (but it may have
# DF set, clear that also)
#
andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
pushl %eax
popfl
movl %esp, %ebx movl %esp, %ebx
pushl %ebx pushl %ebx
andl $-8192, %ebx # GET_THREAD_INFO
movl TI_EXEC_DOMAIN(%ebx), %edx # Get the execution domain
movl 4(%edx), %edx # Get the lcall7 handler for the domain
pushl $0x27 pushl $0x27
call *%edx jmp do_lcall
addl $4, %esp
popl %eax
jmp resume_userspace
ENTRY(ret_from_fork) ENTRY(ret_from_fork)
......
...@@ -1037,6 +1037,16 @@ void blk_stop_queue(request_queue_t *q) ...@@ -1037,6 +1037,16 @@ void blk_stop_queue(request_queue_t *q)
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
/**
* blk_run_queue - run a single device queue
* @q The queue to run
*/
void __blk_run_queue(request_queue_t *q)
{
blk_remove_plug(q);
q->request_fn(q);
}
/** /**
* blk_run_queues - fire all plugged queues * blk_run_queues - fire all plugged queues
* *
...@@ -2198,4 +2208,5 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags); ...@@ -2198,4 +2208,5 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags);
EXPORT_SYMBOL(blk_start_queue); EXPORT_SYMBOL(blk_start_queue);
EXPORT_SYMBOL(blk_stop_queue); EXPORT_SYMBOL(blk_stop_queue);
EXPORT_SYMBOL(__blk_stop_queue); EXPORT_SYMBOL(__blk_stop_queue);
EXPORT_SYMBOL(__blk_run_queue);
EXPORT_SYMBOL(blk_run_queues); EXPORT_SYMBOL(blk_run_queues);
...@@ -669,6 +669,67 @@ void __init scsi_host_init(void) ...@@ -669,6 +669,67 @@ void __init scsi_host_init(void)
} }
} }
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself. For the moment, we include it at the head of
* the host_queue itself - I don't think we want to show this
* to the HA in select_queue_depths(), as this would probably confuse
* matters.
*
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0);
if (sdev) {
scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0)
goto fail;
sdev->borken = 0;
}
return sdev;
fail:
kfree(sdev);
return NULL;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Free a scsi_device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void scsi_free_host_dev(struct scsi_device *sdev)
{
BUG_ON(sdev->id != sdev->host->this_id);
scsi_free_sdev(sdev);
}
void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev) void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -500,15 +500,6 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *); ...@@ -500,15 +500,6 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_unblock_requests(struct Scsi_Host *);
extern void scsi_block_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *);
extern void scsi_report_bus_reset(struct Scsi_Host *, int); extern void scsi_report_bus_reset(struct Scsi_Host *, int);
typedef struct SHN
{
struct list_head shn_list;
char *name;
unsigned short host_no;
unsigned short host_registered;
} Scsi_Host_Name;
extern void scsi_register_blocked_host(struct Scsi_Host *); extern void scsi_register_blocked_host(struct Scsi_Host *);
extern void scsi_deregister_blocked_host(struct Scsi_Host *); extern void scsi_deregister_blocked_host(struct Scsi_Host *);
......
...@@ -155,7 +155,6 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = ...@@ -155,7 +155,6 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
"Enclosure ", "Enclosure ",
}; };
static char * scsi_null_device_strs = "nullnullnullnull";
static const char * const spaces = " "; /* 16 of them */ static const char * const spaces = " "; /* 16 of them */
static unsigned scsi_default_dev_flags; static unsigned scsi_default_dev_flags;
...@@ -2225,6 +2224,8 @@ static int __init init_scsi(void) ...@@ -2225,6 +2224,8 @@ static int __init init_scsi(void)
printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name); printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name);
} }
scsi_init_procfs();
scsi_devfs_handle = devfs_mk_dir(NULL, "scsi", NULL);
scsi_host_init(); scsi_host_init();
scsi_dev_info_list_init(scsi_dev_flags); scsi_dev_info_list_init(scsi_dev_flags);
bus_register(&scsi_driverfs_bus_type); bus_register(&scsi_driverfs_bus_type);
...@@ -2236,9 +2237,10 @@ static void __exit exit_scsi(void) ...@@ -2236,9 +2237,10 @@ static void __exit exit_scsi(void)
{ {
int i; int i;
bus_unregister(&scsi_driverfs_bus_type);
scsi_dev_info_list_delete();
devfs_unregister(scsi_devfs_handle); devfs_unregister(scsi_devfs_handle);
scsi_exit_procfs(); scsi_exit_procfs();
scsi_dev_info_list_delete();
for (i = 0; i < SG_MEMPOOL_NR; i++) { for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
...@@ -2251,95 +2253,3 @@ static void __exit exit_scsi(void) ...@@ -2251,95 +2253,3 @@ static void __exit exit_scsi(void)
module_init(init_scsi); module_init(init_scsi);
module_exit(exit_scsi); module_exit(exit_scsi);
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
*/
Scsi_Device * scsi_get_host_dev(struct Scsi_Host * SHpnt)
{
Scsi_Device * SDpnt;
/*
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself. For the moment, we include it at the head of
* the host_queue itself - I don't think we want to show this
* to the HA in select_queue_depths(), as this would probably confuse
* matters.
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
SDpnt = (Scsi_Device *) kmalloc(sizeof(Scsi_Device),
GFP_ATOMIC);
if(SDpnt == NULL)
return NULL;
memset(SDpnt, 0, sizeof(Scsi_Device));
SDpnt->vendor = scsi_null_device_strs;
SDpnt->model = scsi_null_device_strs;
SDpnt->rev = scsi_null_device_strs;
SDpnt->host = SHpnt;
SDpnt->id = SHpnt->this_id;
SDpnt->type = -1;
SDpnt->new_queue_depth = 1;
scsi_build_commandblocks(SDpnt);
if(SDpnt->current_queue_depth == 0) {
kfree(SDpnt);
return NULL;
}
scsi_initialize_queue(SDpnt, SHpnt);
SDpnt->online = TRUE;
/*
* Initialize the object that we will use to wait for command blocks.
*/
init_waitqueue_head(&SDpnt->scpnt_wait);
return SDpnt;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void scsi_free_host_dev(Scsi_Device * SDpnt)
{
if( (unsigned char) SDpnt->id != (unsigned char) SDpnt->host->this_id )
{
panic("Attempt to delete wrong device\n");
}
blk_cleanup_queue(&SDpnt->request_queue);
/*
* We only have a single SCpnt attached to this device. Free
* it now.
*/
scsi_release_commandblocks(SDpnt);
if (SDpnt->inquiry)
kfree(SDpnt->inquiry);
kfree(SDpnt);
}
...@@ -519,6 +519,13 @@ static inline void scsi_proc_host_add(struct Scsi_Host *); ...@@ -519,6 +519,13 @@ static inline void scsi_proc_host_add(struct Scsi_Host *);
static inline void scsi_proc_host_rm(struct Scsi_Host *); static inline void scsi_proc_host_rm(struct Scsi_Host *);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/*
* Prototypes for functions in scsi_scan.c
*/
extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *,
uint, uint, uint);
extern void scsi_free_sdev(struct scsi_device *);
/* /*
* Prototypes for functions in constants.c * Prototypes for functions in constants.c
* Some of these used to live in constants.h * Some of these used to live in constants.h
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
* use vmalloc() more inquiry+mode_sense [20020302] * use vmalloc() more inquiry+mode_sense [20020302]
* add timers for delayed responses [20020721] * add timers for delayed responses [20020721]
* Patrick Mansfield <patmans@us.ibm.com> max_luns+scsi_level [20021031] * Patrick Mansfield <patmans@us.ibm.com> max_luns+scsi_level [20021031]
* Mike Anderson <andmike@us.ibm.com> sysfs work [20021118]
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -40,6 +41,7 @@ ...@@ -40,6 +41,7 @@
#include <linux/blk.h> #include <linux/blk.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsicam.h>
#include <linux/stat.h> #include <linux/stat.h>
...@@ -49,7 +51,7 @@ ...@@ -49,7 +51,7 @@
#include "scsi_debug.h" #include "scsi_debug.h"
static const char * scsi_debug_version_str = "Version: 1.64 (20021111 2)"; static const char * scsi_debug_version_str = "Version: 1.65 (20021119)";
#ifndef SCSI_CMD_READ_16 #ifndef SCSI_CMD_READ_16
#define SCSI_CMD_READ_16 0x88 #define SCSI_CMD_READ_16 0x88
...@@ -60,24 +62,26 @@ static const char * scsi_debug_version_str = "Version: 1.64 (20021111 2)"; ...@@ -60,24 +62,26 @@ static const char * scsi_debug_version_str = "Version: 1.64 (20021111 2)";
#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
/* A few options that we want selected */ /* Default values for driver parameters */
#define DEF_NR_FAKE_DEVS 1 #define DEF_NR_FAKE_DEVS 1
#define DEF_DEV_SIZE_MB 8 #define DEF_DEV_SIZE_MB 8
#define DEF_FAKE_BLK0 0
#define DEF_EVERY_NTH 100 #define DEF_EVERY_NTH 100
#define DEF_DELAY 1 #define DEF_DELAY 1
#define DEF_MAX_LUNS 2 #define DEF_MAX_LUNS 2
#define DEF_SCSI_LEVEL 3 #define DEF_SCSI_LEVEL 3
#define DEF_NUM_HOST 1 #define DEF_NUM_HOST 1
#define DEF_OPTS 0
#define MAX_NUM_HOSTS 128 #define MAX_NUM_HOSTS 128
#define DEF_OPTS 0 /* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1 #define SCSI_DEBUG_OPT_NOISE 1
#define SCSI_DEBUG_OPT_MEDIUM_ERR 2 #define SCSI_DEBUG_OPT_MEDIUM_ERR 2
#define SCSI_DEBUG_OPT_EVERY_NTH 4 #define SCSI_DEBUG_OPT_EVERY_NTH 4
#define OPT_MEDIUM_ERR_ADDR 0x1234 #define OPT_MEDIUM_ERR_ADDR 0x1234
static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB;
static int scsi_debug_num_devs = DEF_NR_FAKE_DEVS; static int scsi_debug_num_devs = DEF_NR_FAKE_DEVS;
static int scsi_debug_opts = DEF_OPTS; static int scsi_debug_opts = DEF_OPTS;
static int scsi_debug_every_nth = DEF_EVERY_NTH; static int scsi_debug_every_nth = DEF_EVERY_NTH;
...@@ -87,27 +91,30 @@ static int scsi_debug_max_luns = DEF_MAX_LUNS; ...@@ -87,27 +91,30 @@ static int scsi_debug_max_luns = DEF_MAX_LUNS;
static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; static int scsi_debug_scsi_level = DEF_SCSI_LEVEL;
static int scsi_debug_add_host = DEF_NUM_HOST; static int scsi_debug_add_host = DEF_NUM_HOST;
/* This assumes one lun used per allocated target id */
#define N_HEAD 8
#define N_SECTOR 32
#define DEV_READONLY(TGT) (0) #define DEV_READONLY(TGT) (0)
#define DEV_REMOVEABLE(TGT) (0) #define DEV_REMOVEABLE(TGT) (0)
#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK); #define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK);
static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; static unsigned long sdebug_store_size; /* in bytes */
#define STORE_SIZE (scsi_debug_dev_size_mb * 1024 * 1024) static sector_t sdebug_capacity; /* in sectors */
/* old BIOS stuff, kernel may get rid of them but some mode sense pages
may still need them */
static int sdebug_heads; /* heads per disk */
static int sdebug_cylinders_per; /* cylinders per surface */
static int sdebug_sectors_per; /* sectors per cylinder */
/* default sector size is 512 bytes, 2**9 bytes */ /* default sector size is 512 bytes, 2**9 bytes */
#define POW2_SECT_SIZE 9 #define POW2_SECT_SIZE 9
#define SECT_SIZE (1 << POW2_SECT_SIZE) #define SECT_SIZE (1 << POW2_SECT_SIZE)
#define N_CYLINDER (STORE_SIZE / (SECT_SIZE * N_SECTOR * N_HEAD))
/* Time to wait before completing a command */
#define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER)
#define SECT_SIZE_PER(TGT) SECT_SIZE #define SECT_SIZE_PER(TGT) SECT_SIZE
struct Scsi_Host *scsi_debug_hosts[MAX_NUM_HOSTS]; struct sdebug_host_info {
struct Scsi_Host *shost;
struct device *dev;
};
struct sdebug_host_info * scsi_debug_hosts;
#define SDEBUG_SENSE_LEN 32 #define SDEBUG_SENSE_LEN 32
...@@ -145,7 +152,10 @@ static int num_host_resets = 0; ...@@ -145,7 +152,10 @@ static int num_host_resets = 0;
static spinlock_t queued_arr_lock = SPIN_LOCK_UNLOCKED; static spinlock_t queued_arr_lock = SPIN_LOCK_UNLOCKED;
static rwlock_t atomic_rw = RW_LOCK_UNLOCKED; static rwlock_t atomic_rw = RW_LOCK_UNLOCKED;
static struct device_driver sdebug_driverfs_driver; static char sdebug_proc_name[] = "scsi_debug";
static struct device_driver sdebug_driverfs_driver = {
.name = sdebug_proc_name,
};
/* function declarations */ /* function declarations */
static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff, static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff,
...@@ -175,8 +185,15 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, ...@@ -175,8 +185,15 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
const char * dev_id_str, int dev_id_str_len); const char * dev_id_str, int dev_id_str_len);
static void do_create_driverfs_files(void); static void do_create_driverfs_files(void);
static void do_remove_driverfs_files(void); static void do_remove_driverfs_files(void);
static struct Scsi_Host * sdebug_add_shost(void); static void sdebug_add_shost(int num);
static void sdebug_remove_shost(int num);
static int sdebug_add_adapter(int num);
static void sdebug_remove_adapter(int num);
static struct device pseudo_primary;
static struct bus_type pseudo_lld_bus;
int scsi_debug_register_driver(struct device_driver *);
int scsi_debug_unregister_driver(struct device_driver *);
static unsigned char * scatg2virt(const struct scatterlist * sclp) static unsigned char * scatg2virt(const struct scatterlist * sclp)
{ {
...@@ -193,13 +210,12 @@ static ...@@ -193,13 +210,12 @@ static
int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
{ {
unsigned char *cmd = (unsigned char *) SCpnt->cmnd; unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
int block; int block, upper_blk, num;
int upper_blk;
unsigned char *buff; unsigned char *buff;
int errsts = 0; int errsts = 0;
int target = SCpnt->target; int target = SCpnt->target;
int bufflen = SCpnt->request_bufflen; int bufflen = SCpnt->request_bufflen;
int num, capac; unsigned long capac;
struct sdebug_dev_info * devip = NULL; struct sdebug_dev_info * devip = NULL;
unsigned char * sbuff; unsigned char * sbuff;
...@@ -230,11 +246,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) ...@@ -230,11 +246,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
if (SCpnt->lun >= scsi_debug_max_luns) if (SCpnt->lun >= scsi_debug_max_luns)
return schedule_resp(SCpnt, NULL, done, return schedule_resp(SCpnt, NULL, done,
DID_NO_CONNECT << 16, 0); DID_NO_CONNECT << 16, 0);
#if 0
printk(KERN_INFO "sdebug:qc: host_no=%u, id=%u, sdp=%p, cmd=0x%x\n",
(int)SCpnt->device->host->host_no, (int)SCpnt->device->id,
SCpnt->device, (int)*cmd);
#endif
devip = devInfoReg(SCpnt); devip = devInfoReg(SCpnt);
if (NULL == devip) if (NULL == devip)
return schedule_resp(SCpnt, NULL, done, return schedule_resp(SCpnt, NULL, done,
...@@ -302,7 +313,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) ...@@ -302,7 +313,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
errsts = check_reset(SCpnt, devip); errsts = check_reset(SCpnt, devip);
memset(buff, 0, bufflen); memset(buff, 0, bufflen);
if (bufflen > 7) { if (bufflen > 7) {
capac = CAPACITY - 1; capac = (unsigned long)sdebug_capacity - 1;
buff[0] = (capac >> 24); buff[0] = (capac >> 24);
buff[1] = (capac >> 16) & 0xff; buff[1] = (capac >> 16) & 0xff;
buff[2] = (capac >> 8) & 0xff; buff[2] = (capac >> 8) & 0xff;
...@@ -382,10 +393,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) ...@@ -382,10 +393,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
memset(buff, 0, bufflen); memset(buff, 0, bufflen);
break; break;
default: default:
#if 0
printk(KERN_INFO "scsi_debug: Unsupported command, "
"opcode=0x%x\n", (int)cmd[0]);
#endif
if ((errsts = check_reset(SCpnt, devip))) if ((errsts = check_reset(SCpnt, devip)))
break; break;
mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x20, 0, 14); mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x20, 0, 14);
...@@ -543,8 +550,8 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target) ...@@ -543,8 +550,8 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target)
0, 0, 0, 0, 0x40, 0, 0, 0}; 0, 0, 0, 0, 0x40, 0, 0, 0};
memcpy(p, format_pg, sizeof(format_pg)); memcpy(p, format_pg, sizeof(format_pg));
p[10] = (N_SECTOR >> 8) & 0xff; p[10] = (sdebug_sectors_per >> 8) & 0xff;
p[11] = N_SECTOR & 0xff; p[11] = sdebug_sectors_per & 0xff;
p[12] = (SECT_SIZE >> 8) & 0xff; p[12] = (SECT_SIZE >> 8) & 0xff;
p[13] = SECT_SIZE & 0xff; p[13] = SECT_SIZE & 0xff;
if (DEV_REMOVEABLE(target)) if (DEV_REMOVEABLE(target))
...@@ -673,7 +680,7 @@ static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, ...@@ -673,7 +680,7 @@ static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int bufflen = SCpnt->request_bufflen; int bufflen = SCpnt->request_bufflen;
unsigned long iflags; unsigned long iflags;
if (upper_blk || (block + num > CAPACITY)) { if (upper_blk || (block + num > sdebug_capacity)) {
mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14); mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
} }
...@@ -722,7 +729,7 @@ static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, ...@@ -722,7 +729,7 @@ static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int bufflen = SCpnt->request_bufflen; int bufflen = SCpnt->request_bufflen;
unsigned long iflags; unsigned long iflags;
if (upper_blk || (block + num > CAPACITY)) { if (upper_blk || (block + num > sdebug_capacity)) {
mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14); mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14);
return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
} }
...@@ -805,8 +812,6 @@ static void timer_intr_handler(unsigned long indx) ...@@ -805,8 +812,6 @@ static void timer_intr_handler(unsigned long indx)
spin_unlock_irqrestore(&queued_arr_lock, iflags); spin_unlock_irqrestore(&queued_arr_lock, iflags);
} }
static const char * sdebug_proc_name = "scsi_debug";
static int scsi_debug_slave_attach(struct scsi_device * sdp) static int scsi_debug_slave_attach(struct scsi_device * sdp)
{ {
int k; int k;
...@@ -910,14 +915,22 @@ static int scsi_debug_abort(struct scsi_cmnd * SCpnt) ...@@ -910,14 +915,22 @@ static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
static int scsi_debug_biosparam(struct scsi_device *sdev, static int scsi_debug_biosparam(struct scsi_device *sdev,
struct block_device * bdev, sector_t capacity, int *info) struct block_device * bdev, sector_t capacity, int *info)
{ {
int res;
unsigned char *buf;
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: biosparam\n"); printk(KERN_INFO "scsi_debug: biosparam\n");
/* int size = capacity; */ buf = scsi_bios_ptable(bdev);
info[0] = N_HEAD; if (buf) {
info[1] = N_SECTOR; res = scsi_partsize(buf, capacity,
info[2] = N_CYLINDER; &info[2], &info[0], &info[1]);
if (info[2] >= 1024) kfree(buf);
info[2] = 1024; if (! res)
return res;
}
info[0] = sdebug_heads;
info[1] = sdebug_sectors_per;
info[2] = sdebug_cylinders_per;
return 0; return 0;
} }
...@@ -1289,7 +1302,7 @@ static int scsi_debug_proc_info(char *buffer, char **start, off_t offset, ...@@ -1289,7 +1302,7 @@ static int scsi_debug_proc_info(char *buffer, char **start, off_t offset,
scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth,
scsi_debug_cmnd_count, scsi_debug_delay, scsi_debug_cmnd_count, scsi_debug_delay,
scsi_debug_max_luns, scsi_debug_scsi_level, scsi_debug_max_luns, scsi_debug_scsi_level,
SECT_SIZE, N_CYLINDER, N_HEAD, N_SECTOR, SECT_SIZE, sdebug_cylinders_per, sdebug_heads, sdebug_sectors_per,
num_aborts, num_dev_resets, num_bus_resets, num_host_resets); num_aborts, num_dev_resets, num_bus_resets, num_host_resets);
if (pos < offset) { if (pos < offset) {
len = 0; len = 0;
...@@ -1402,7 +1415,6 @@ static ssize_t sdebug_add_host_read(struct device_driver * ddp, char * buf, ...@@ -1402,7 +1415,6 @@ static ssize_t sdebug_add_host_read(struct device_driver * ddp, char * buf,
static ssize_t sdebug_add_host_write(struct device_driver * ddp, static ssize_t sdebug_add_host_write(struct device_driver * ddp,
const char * buf, size_t count, loff_t off) const char * buf, size_t count, loff_t off)
{ {
struct Scsi_Host * hpnt;
int delta_hosts, k; int delta_hosts, k;
char work[20]; char work[20];
...@@ -1410,14 +1422,21 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp, ...@@ -1410,14 +1422,21 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp,
return 0; return 0;
if (1 != sscanf(buf, "%10s", work)) if (1 != sscanf(buf, "%10s", work))
return -EINVAL; return -EINVAL;
if (1 != sscanf(work, "%d", &delta_hosts)) { /* temporary hack around sscanf() problem with -ve nums */
return -EINVAL; int neg = 0;
if ('-' == *work)
neg = 1;
if (1 != sscanf(work + neg, "%d", &delta_hosts))
return -EINVAL;
if (neg)
delta_hosts = -delta_hosts;
}
if (delta_hosts > 0) { if (delta_hosts > 0) {
do { do {
for (k = 0; k < MAX_NUM_HOSTS; ++k) { for (k = 0; k < MAX_NUM_HOSTS; ++k) {
if (NULL == scsi_debug_hosts[k]) { if (NULL == scsi_debug_hosts[k].shost) {
hpnt = sdebug_add_shost(); sdebug_add_shost(k);
scsi_debug_hosts[k] = hpnt;
break; break;
} }
} }
...@@ -1428,10 +1447,8 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp, ...@@ -1428,10 +1447,8 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp,
} else if (delta_hosts < 0) { } else if (delta_hosts < 0) {
do { do {
for (k = MAX_NUM_HOSTS - 1; k >= 0; --k) { for (k = MAX_NUM_HOSTS - 1; k >= 0; --k) {
if (scsi_debug_hosts[k]) { if (scsi_debug_hosts[k].shost) {
scsi_remove_host(scsi_debug_hosts[k]); sdebug_remove_shost(k);
scsi_unregister(scsi_debug_hosts[k]);
scsi_debug_hosts[k] = NULL;
break; break;
} }
} }
...@@ -1469,30 +1486,65 @@ static void do_remove_driverfs_files() ...@@ -1469,30 +1486,65 @@ static void do_remove_driverfs_files()
driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay); driver_remove_file(&sdebug_driverfs_driver, &driver_attr_delay);
} }
static struct Scsi_Host * sdebug_add_shost(void) static void sdebug_add_shost(int num)
{ {
struct Scsi_Host * hpnt; struct Scsi_Host * hpnt;
int err; int err;
if (sdebug_add_adapter(num)){
printk(KERN_ERR "sdebug_add_shost: sdebug_add_adapter failed\n");
return;
}
hpnt = scsi_register(&sdebug_driver_template, 0); hpnt = scsi_register(&sdebug_driver_template, 0);
if (NULL == hpnt) { if (NULL == hpnt) {
sdebug_remove_adapter(num);
printk(KERN_ERR "sdebug_add_shost: scsi_register failed\n"); printk(KERN_ERR "sdebug_add_shost: scsi_register failed\n");
return NULL; return;
} }
err = scsi_add_host(hpnt); err = scsi_add_host(hpnt);
if (err) { if (err) {
printk(KERN_ERR "sdebug_add_shost: scsi_add_host failed\n"); printk(KERN_ERR "sdebug_add_shost: scsi_add_host failed\n");
scsi_unregister(hpnt); scsi_unregister(hpnt);
return NULL; sdebug_remove_adapter(num);
return;
} }
hpnt->max_lun = scsi_debug_max_luns; hpnt->max_lun = scsi_debug_max_luns;
return hpnt;
scsi_debug_hosts[num].shost = hpnt;
} }
static void sdebug_remove_shost(int num)
{
scsi_remove_host(scsi_debug_hosts[num].shost);
scsi_unregister(scsi_debug_hosts[num].shost);
sdebug_remove_adapter(num);
scsi_debug_hosts[num].shost = NULL;
}
static int __init scsi_debug_init(void) static int __init scsi_debug_init(void)
{ {
int sz, k; unsigned long sz;
int k;
sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576;
sdebug_capacity = sdebug_store_size / SECT_SIZE;
/* play around with geometry, don't waste too much on track 0 */
sdebug_heads = 8;
sdebug_sectors_per = 32;
if (scsi_debug_dev_size_mb >= 16)
sdebug_heads = 32;
else if (scsi_debug_dev_size_mb >= 256)
sdebug_heads = 64;
sdebug_cylinders_per = (unsigned long)sdebug_capacity /
(sdebug_sectors_per * sdebug_heads);
if (sdebug_cylinders_per >= 1024) {
/* other LLDs do this; implies >= 1GB ram disk ... */
sdebug_heads = 255;
sdebug_sectors_per = 63;
sdebug_cylinders_per = (unsigned long)sdebug_capacity /
(sdebug_sectors_per * sdebug_heads);
}
if (scsi_debug_num_devs > 0) { if (scsi_debug_num_devs > 0) {
sz = sizeof(struct sdebug_dev_info) * scsi_debug_num_devs; sz = sizeof(struct sdebug_dev_info) * scsi_debug_num_devs;
...@@ -1504,7 +1556,15 @@ static int __init scsi_debug_init(void) ...@@ -1504,7 +1556,15 @@ static int __init scsi_debug_init(void)
memset(devInfop, 0, sz); memset(devInfop, 0, sz);
} }
sz = STORE_SIZE; sz = sizeof(struct sdebug_host_info) * MAX_NUM_HOSTS;
scsi_debug_hosts = vmalloc(sz);
if (NULL == scsi_debug_hosts) {
printk(KERN_ERR "scsi_debug_init: out of memory 1\n");
return -ENOMEM;
}
memset(scsi_debug_hosts, 0, sz);
sz = sdebug_store_size;
fake_storep = vmalloc(sz); fake_storep = vmalloc(sz);
if (NULL == fake_storep) { if (NULL == fake_storep) {
printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); printk(KERN_ERR "scsi_debug_init: out of memory, 1\n");
...@@ -1516,23 +1576,22 @@ static int __init scsi_debug_init(void) ...@@ -1516,23 +1576,22 @@ static int __init scsi_debug_init(void)
init_all_queued(); init_all_queued();
sdebug_driverfs_driver.name = (char *)sdebug_proc_name; device_register(&pseudo_primary);
sdebug_driverfs_driver.bus = &scsi_driverfs_bus_type; bus_register(&pseudo_lld_bus);
driver_register(&sdebug_driverfs_driver); scsi_debug_register_driver(&sdebug_driverfs_driver);
do_create_driverfs_files(); do_create_driverfs_files();
sdebug_driver_template.proc_name = (char *)sdebug_proc_name; sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
memset(scsi_debug_hosts, 0, sizeof(struct Scsi_Host *) * MAX_NUM_HOSTS);
for (k = 0; (k < scsi_debug_add_host) && (k < MAX_NUM_HOSTS); k++) { for (k = 0; (k < scsi_debug_add_host) && (k < MAX_NUM_HOSTS); k++) {
scsi_debug_hosts[k] = sdebug_add_shost(); sdebug_add_shost(k);
if (NULL == scsi_debug_hosts[k]) { if (NULL == scsi_debug_hosts[k].shost) {
printk(KERN_ERR "scsi_debug_init: " printk(KERN_ERR "scsi_debug_init: "
"sdebug_add_shost failed k=%d\n", k); "sdebug_add_shost failed k=%d\n", k);
break; break;
} }
} }
scsi_debug_add_host = k; // number of hosts actually present scsi_debug_add_host = k; // number of hosts actually present
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
printk(KERN_INFO "scsi_debug: ... built %d host(s)\n", printk(KERN_INFO "scsi_debug: ... built %d host(s)\n",
...@@ -1546,20 +1605,78 @@ static void __exit scsi_debug_exit(void) ...@@ -1546,20 +1605,78 @@ static void __exit scsi_debug_exit(void)
int k; int k;
for (k = MAX_NUM_HOSTS - 1; k >= 0; --k) { for (k = MAX_NUM_HOSTS - 1; k >= 0; --k) {
if (scsi_debug_hosts[k]) { if (scsi_debug_hosts[k].shost) {
scsi_remove_host(scsi_debug_hosts[k]); sdebug_remove_shost(k);
scsi_unregister(scsi_debug_hosts[k]);
scsi_debug_hosts[k] = NULL;
} }
} }
stop_all_queued(); stop_all_queued();
do_remove_driverfs_files(); do_remove_driverfs_files();
driver_unregister(&sdebug_driverfs_driver); scsi_debug_unregister_driver(&sdebug_driverfs_driver);
bus_unregister(&pseudo_lld_bus);
device_unregister(&pseudo_primary);
vfree(fake_storep); vfree(fake_storep);
if (devInfop) if (devInfop)
vfree(devInfop); vfree(devInfop);
} }
module_init(scsi_debug_init); device_initcall(scsi_debug_init);
module_exit(scsi_debug_exit); module_exit(scsi_debug_exit);
static struct device pseudo_primary = {
.name = "Host/Pseudo Bridge",
.bus_id = "pseudo_0",
};
static int pseudo_lld_bus_match(struct device *dev,
struct device_driver *dev_driver)
{
return 1;
}
static struct bus_type pseudo_lld_bus = {
name: "pseudo",
match: pseudo_lld_bus_match,
};
int scsi_debug_register_driver(struct device_driver *dev_driver)
{
dev_driver->bus = &pseudo_lld_bus;
driver_register(dev_driver);
return 0;
}
int scsi_debug_unregister_driver(struct device_driver *dev_driver)
{
driver_unregister(dev_driver);
return 0;
}
static int sdebug_add_adapter(int num)
{
struct device * dev;
dev = kmalloc(sizeof(*dev),GFP_KERNEL);
if (NULL == dev) {
printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
return 1;
}
memset(dev, 0, sizeof(*dev));
dev->bus = &pseudo_lld_bus;
dev->parent = &pseudo_primary;
sprintf(dev->name, "scsi debug adapter");
sprintf(dev->bus_id, "adapter%d", num);
device_register(dev);
scsi_debug_hosts[num].dev = dev;
return 0;
}
static void sdebug_remove_adapter(int num)
{
device_unregister(scsi_debug_hosts[num].dev);
}
...@@ -43,6 +43,7 @@ static Scsi_Host_Template sdebug_driver_template = { ...@@ -43,6 +43,7 @@ static Scsi_Host_Template sdebug_driver_template = {
.max_sectors = 4096, .max_sectors = 4096,
.unchecked_isa_dma = 0, .unchecked_isa_dma = 0,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.module = THIS_MODULE,
}; };
#endif #endif
...@@ -1479,8 +1479,6 @@ static void scsi_restart_operations(struct Scsi_Host *shost) ...@@ -1479,8 +1479,6 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
*/ */
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
request_queue_t *q = &sdev->request_queue;
if ((shost->can_queue > 0 && if ((shost->can_queue > 0 &&
(shost->host_busy >= shost->can_queue)) (shost->host_busy >= shost->can_queue))
|| (shost->host_blocked) || (shost->host_blocked)
...@@ -1488,7 +1486,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) ...@@ -1488,7 +1486,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
break; break;
} }
q->request_fn(q); __blk_run_queue(&sdev->request_queue);
} }
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
} }
......
...@@ -7,49 +7,18 @@ ...@@ -7,49 +7,18 @@
* of people at Linux Expo. * of people at Linux Expo.
*/ */
/*
* The fundamental purpose of this file is to contain a library of utility
* routines that can be used by low-level drivers. Ultimately the idea
* is that there should be a sufficiently rich number of functions that it
* would be possible for a driver author to fashion a queueing function for
* a low-level driver if they wished. Note however that this file also
* contains the "default" versions of these functions, as we don't want to
* go through and retrofit queueing functions into all 30 some-odd drivers.
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/ioport.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/dma.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
/*
* This entire source file deals with the new queueing code.
*/
/* /*
* Function: scsi_insert_special_cmd() * Function: scsi_insert_special_cmd()
* *
...@@ -259,7 +228,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -259,7 +228,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
/* /*
* Just hit the requeue function for the queue. * Just hit the requeue function for the queue.
*/ */
q->request_fn(q); __blk_run_queue(q);
SDpnt = (Scsi_Device *) q->queuedata; SDpnt = (Scsi_Device *) q->queuedata;
SHpnt = SDpnt->host; SHpnt = SDpnt->host;
...@@ -272,8 +241,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -272,8 +241,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* use function pointers to pick the right one. * use function pointers to pick the right one.
*/ */
if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) { if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) {
request_queue_t *q;
for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
if (((SHpnt->can_queue > 0) if (((SHpnt->can_queue > 0)
&& (SHpnt->host_busy >= SHpnt->can_queue)) && (SHpnt->host_busy >= SHpnt->can_queue))
...@@ -283,8 +250,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -283,8 +250,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
break; break;
} }
q = &SDpnt->request_queue; __blk_run_queue(&SDpnt->request_queue);
q->request_fn(q);
} }
} }
...@@ -299,7 +265,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -299,7 +265,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
all_clear = 1; all_clear = 1;
if (SHpnt->some_device_starved) { if (SHpnt->some_device_starved) {
for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
request_queue_t *q;
if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue)) if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
|| (SHpnt->host_blocked) || (SHpnt->host_blocked)
|| (SHpnt->host_self_blocked)) { || (SHpnt->host_self_blocked)) {
...@@ -308,8 +273,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -308,8 +273,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
if (SDpnt->device_blocked || !SDpnt->starved) { if (SDpnt->device_blocked || !SDpnt->starved) {
continue; continue;
} }
q = &SDpnt->request_queue; __blk_run_queue(&SDpnt->request_queue);
q->request_fn(q);
all_clear = 0; all_clear = 0;
} }
if (SDpnt == NULL && all_clear) { if (SDpnt == NULL && all_clear) {
...@@ -1021,10 +985,11 @@ void scsi_request_fn(request_queue_t * q) ...@@ -1021,10 +985,11 @@ void scsi_request_fn(request_queue_t * q)
break; break;
if(!req) { if(!req) {
/* can happen if the prep fails /* If the device is busy, a returning I/O
* FIXME: elv_next_request() should be plugging the * will restart the queue. Otherwise, we have
* queue */ * to plug the queue */
blk_plug_device(q); if(SDpnt->device_busy == 0)
blk_plug_device(q);
break; break;
} }
......
...@@ -607,25 +607,9 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -607,25 +607,9 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
if (sdev->attached == 0) { if (sdev->attached == 0) {
devfs_unregister (sdev->de); devfs_unregister (sdev->de);
scsi_free_sdev(sdev);
/* Now we can remove the device structure */ err = 0;
if (sdev->next != NULL)
sdev->next->prev = sdev->prev;
if (sdev->prev != NULL)
sdev->prev->next = sdev->next;
if (shost->host_queue == sdev) {
shost->host_queue = sdev->next;
}
blk_cleanup_queue(&sdev->request_queue);
if (sdev->inquiry)
kfree(sdev->inquiry);
kfree((char *) sdev);
} else {
goto out;
} }
err = 0;
} }
out: out:
......
...@@ -465,12 +465,12 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd) ...@@ -465,12 +465,12 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Return value: * Return value:
* Scsi_Device pointer, or NULL on failure. * Scsi_Device pointer, or NULL on failure.
**/ **/
static Scsi_Device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
uint id, uint lun) uint id, uint lun)
{ {
Scsi_Device *sdev; struct scsi_device *sdev;
sdev = (Scsi_Device *) kmalloc(sizeof(Scsi_Device), GFP_ATOMIC); sdev = kmalloc(sizeof(*sdev), GFP_ATOMIC);
if (sdev == NULL) if (sdev == NULL)
printk(ALLOC_FAILURE_MSG, __FUNCTION__); printk(ALLOC_FAILURE_MSG, __FUNCTION__);
else { else {
...@@ -522,7 +522,7 @@ static Scsi_Device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -522,7 +522,7 @@ static Scsi_Device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
* Undo the actions in scsi_alloc_sdev, including removing @sdev from * Undo the actions in scsi_alloc_sdev, including removing @sdev from
* the list, and freeing @sdev. * the list, and freeing @sdev.
**/ **/
static void scsi_free_sdev(Scsi_Device *sdev) void scsi_free_sdev(struct scsi_device *sdev)
{ {
if (sdev->prev != NULL) if (sdev->prev != NULL)
sdev->prev->next = sdev->next; sdev->prev->next = sdev->next;
......
...@@ -758,6 +758,7 @@ static void matrox_cfb8_revc(struct display* p, int xx, int yy) { ...@@ -758,6 +758,7 @@ static void matrox_cfb8_revc(struct display* p, int xx, int yy) {
} }
#endif #endif
#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
static void matrox_cfbX_revc(struct display* p, int xx, int yy) { static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
CRITFLAGS CRITFLAGS
MINFO_FROM_DISP(p); MINFO_FROM_DISP(p);
...@@ -778,6 +779,7 @@ static void matrox_cfbX_revc(struct display* p, int xx, int yy) { ...@@ -778,6 +779,7 @@ static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
CRITEND CRITEND
} }
#endif
static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) { static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
unsigned int bottom_height, right_width; unsigned int bottom_height, right_width;
......
...@@ -849,7 +849,7 @@ static int parse_pins4(WPMINFO const struct matrox_bios* bd) { ...@@ -849,7 +849,7 @@ static int parse_pins4(WPMINFO const struct matrox_bios* bd) {
( bd->pins[86] & 0x0000000F); ( bd->pins[86] & 0x0000000F);
MINFO->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) | MINFO->values.reg.opt = ((bd->pins[53] << 15) & 0x00400000) |
((bd->pins[53] << 22) & 0x10000000) | ((bd->pins[53] << 22) & 0x10000000) |
((bd->pins[53] << 10) & 0x00001C00); ((bd->pins[53] << 7) & 0x00001C00);
MINFO->values.reg.opt3 = get_u32(bd->pins + 67); MINFO->values.reg.opt3 = get_u32(bd->pins + 67);
MINFO->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000; MINFO->values.pll.system = (bd->pins[ 65] == 0xFF) ? 200000 : bd->pins[ 65] * 4000;
MINFO->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000; MINFO->features.pll.ref_freq = (bd->pins[ 92] & 0x01) ? 14318 : 27000;
......
...@@ -909,7 +909,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, ...@@ -909,7 +909,7 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
if (S_ISREG(mode) && if (S_ISREG(mode) &&
(server->m.flags & NCP_MOUNT_EXTRAS) && (server->m.flags & NCP_MOUNT_EXTRAS) &&
(mode & S_IXUGO)) (mode & S_IXUGO))
attributes |= aSYSTEM; attributes |= aSYSTEM | aSHARED;
result = ncp_open_create_file_or_subdir(server, dir, __name, result = ncp_open_create_file_or_subdir(server, dir, __name,
OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
......
...@@ -321,6 +321,7 @@ extern int scsi_cmd_ioctl(struct block_device *, unsigned int, unsigned long); ...@@ -321,6 +321,7 @@ extern int scsi_cmd_ioctl(struct block_device *, unsigned int, unsigned long);
extern void blk_start_queue(request_queue_t *q); extern void blk_start_queue(request_queue_t *q);
extern void blk_stop_queue(request_queue_t *q); extern void blk_stop_queue(request_queue_t *q);
extern void __blk_stop_queue(request_queue_t *q); extern void __blk_stop_queue(request_queue_t *q);
extern void __blk_run_queue(request_queue_t *q);
static inline request_queue_t *bdev_get_queue(struct block_device *bdev) static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
{ {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
struct scsi_device;
/* /*
* Structures used for scsi_ioctl et al. * Structures used for scsi_ioctl et al.
*/ */
...@@ -33,19 +35,15 @@ typedef struct scsi_idlun { ...@@ -33,19 +35,15 @@ typedef struct scsi_idlun {
} Scsi_Idlun; } Scsi_Idlun;
/* Fibre Channel WWN, port_id struct */ /* Fibre Channel WWN, port_id struct */
typedef struct scsi_fctargaddress typedef struct scsi_fctargaddress {
{
__u32 host_port_id; __u32 host_port_id;
unsigned char host_wwn[8]; // include NULL term. unsigned char host_wwn[8]; // include NULL term.
} Scsi_FCTargAddress; } Scsi_FCTargAddress;
extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg); extern int scsi_ioctl(struct scsi_device *, int, void *);
extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg); extern int kernel_scsi_ioctl(struct scsi_device *, int , void *);
extern int scsi_ioctl_send_command(Scsi_Device *dev, extern int scsi_ioctl_send_command(struct scsi_device *,
Scsi_Ioctl_Command *arg); struct scsi_ioctl_command *);
#endif
#endif
#endif /* __KERNEL__ */
#endif /* _SCSI_IOCTL_H */
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