Commit 1b75d964 authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/scsi-misc-2.5

into mulgrave.(none):/home/jejb/BK/scsi-misc-new-2.5
parents c9e54010 45f841b0
......@@ -124,8 +124,6 @@
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/mca.h>
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/io.h>
......@@ -236,7 +234,7 @@ static __u8 NCR_700_SDTR_msg[] = {
NCR_700_MAX_OFFSET
};
struct Scsi_Host * __init
struct Scsi_Host *
NCR_700_detect(Scsi_Host_Template *tpnt,
struct NCR_700_Host_Parameters *hostdata)
{
......@@ -2020,3 +2018,5 @@ NCR_700_slave_destroy(Scsi_Device *SDp)
EXPORT_SYMBOL(NCR_700_detect);
EXPORT_SYMBOL(NCR_700_release);
EXPORT_SYMBOL(NCR_700_intr);
no_module_init;
......@@ -22,11 +22,11 @@ static int D700_release(struct Scsi_Host *host);
* remaining parameters shown below must be filled in. The 53c700
* routine NCR_700_detect will fill in all of the missing routines */
#define NCR_D700_SCSI { \
name: "NCR Dual 700 MCA", \
proc_name: "NCR_D700", \
detect: D700_detect, \
release: D700_release, \
this_id: 7, \
.name = "NCR Dual 700 MCA", \
.proc_name = "NCR_D700", \
.detect = D700_detect, \
.release = D700_release, \
.this_id = 7, \
}
......
......@@ -36,7 +36,6 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/smp_lock.h>
#define __KERNEL_SYSCALLS__
......@@ -50,7 +49,6 @@ static LIST_HEAD(scsi_host_list);
static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
static int scsi_host_next_hn; /* host_no for next new host */
static int scsi_hosts_registered; /* cnt of registered scsi hosts */
static char *scsihosts;
MODULE_PARM(scsihosts, "s");
......@@ -192,7 +190,7 @@ static void scsi_host_legacy_release(struct Scsi_Host *shost)
static int scsi_remove_legacy_host(struct Scsi_Host *shost)
{
int error, pcount = scsi_hosts_registered;
int error;
error = scsi_remove_host(shost);
if (error)
......@@ -203,8 +201,6 @@ static int scsi_remove_legacy_host(struct Scsi_Host *shost)
else
scsi_host_legacy_release(shost);
if (pcount == scsi_hosts_registered)
scsi_unregister(shost);
return 0;
}
......@@ -260,7 +256,6 @@ static int scsi_check_device_busy(struct scsi_device *sdev)
int scsi_remove_host(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
struct list_head *le, *lh;
/*
* FIXME Do ref counting. We force all of the devices offline to
......@@ -287,16 +282,9 @@ int scsi_remove_host(struct Scsi_Host *shost)
sdev->attached);
return 1;
}
devfs_unregister(sdev->de);
device_unregister(&sdev->sdev_driverfs_dev);
}
/* Next we free up the Scsi_Cmnd structures for this host */
list_for_each_safe(le, lh, &shost->my_devices) {
scsi_free_sdev(list_entry(le, Scsi_Device, siblings));
}
scsi_forget_host(shost);
return 0;
}
......@@ -343,7 +331,6 @@ void scsi_unregister(struct Scsi_Host *shost)
shost->eh_notify = NULL;
}
scsi_hosts_registered--;
shost->hostt->present--;
/* Cleanup proc and driverfs */
......@@ -395,7 +382,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes);
shost->host_no = scsi_alloc_host_num(shost_tp->proc_name);
scsi_hosts_registered++;
spin_lock_init(&shost->default_lock);
scsi_assign_lock(shost, &shost->default_lock);
......@@ -491,7 +477,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
int scsi_register_host(Scsi_Host_Template *shost_tp)
{
struct Scsi_Host *shost;
int cur_cnt;
/*
* Check no detect routine.
......@@ -503,8 +488,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
if (!shost_tp->max_sectors)
shost_tp->max_sectors = 1024;
cur_cnt = scsi_hosts_registered;
/*
* The detect routine must carefully spinunlock/spinlock if it
* enables interrupts, since all interrupt handlers do spinlock as
......@@ -520,28 +503,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
if (!shost_tp->present)
return 0;
if (cur_cnt == scsi_hosts_registered) {
if (shost_tp->present > 1) {
printk(KERN_ERR "scsi: Failure to register"
"low-level scsi driver");
scsi_unregister_host(shost_tp);
return 1;
}
/*
* The low-level driver failed to register a driver.
* We can do this now.
*
* XXX Who needs manual registration and why???
*/
if (!scsi_register(shost_tp, 0)) {
printk(KERN_ERR "scsi: register failed.\n");
scsi_unregister_host(shost_tp);
return 1;
}
}
/*
* XXX(hch) use scsi_tp_for_each_host() once it propagates
* error returns properly.
......@@ -575,20 +536,7 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
**/
int scsi_unregister_host(Scsi_Host_Template *shost_tp)
{
int pcount;
/* get the big kernel lock, so we don't race with open() */
lock_kernel();
pcount = scsi_hosts_registered;
scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host);
if (pcount != scsi_hosts_registered)
printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
(scsi_hosts_registered == 1) ? "" : "s");
unlock_kernel();
return 0;
}
......@@ -668,64 +616,6 @@ 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.
*
* 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)
{
unsigned long flags;
......@@ -765,22 +655,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost)
}
spin_unlock_irqrestore(shost->host_lock, flags);
}
/*
* 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:
*/
......@@ -532,6 +532,8 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost,
* Prototypes for functions/data in scsi_scan.c
*/
extern void scsi_scan_host(struct Scsi_Host *);
extern void scsi_forget_host(struct Scsi_Host *);
struct Scsi_Device_Template
{
......
This diff is collapsed.
......@@ -510,7 +510,7 @@ typedef struct os_header_s {
#define OS_AUX_SIZE (512)
//#define OSST_MAX_SG 2
/* The tape buffer descriptor. */
/* The OnStream tape buffer descriptor. */
typedef struct {
unsigned char in_use;
unsigned char dma; /* DMA-able buffer */
......@@ -524,13 +524,13 @@ typedef struct {
Scsi_Request *last_SRpnt;
unsigned char *b_data;
os_aux_t *aux; /* onstream AUX structure at end of each block */
unsigned short use_sg; /* zero or number of segments for this adapter */
unsigned short sg_segs; /* total number of allocated segments */
unsigned short use_sg; /* zero or number of s/g segments for this adapter */
unsigned short sg_segs; /* number of segments in s/g list */
unsigned short orig_sg_segs; /* number of segments allocated at first try */
struct scatterlist sg[1]; /* MUST BE last item */
} OSST_buffer;
/* The tape drive descriptor */
/* The OnStream tape drive descriptor */
typedef struct {
struct Scsi_Device_Template *driver;
unsigned capacity;
......@@ -549,6 +549,7 @@ typedef struct {
unsigned char restr_dma;
unsigned char scsi2_logical;
unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */
unsigned char pos_unknown; /* after reset position unknown */
int write_threshold;
int timeout; /* timeout for normal commands */
int long_timeout; /* timeout for commands known to take long time*/
......@@ -556,10 +557,10 @@ typedef struct {
/* Mode characteristics */
ST_mode modes[ST_NBR_MODES];
int current_mode;
#ifdef CONFIG_DEVFS_FS
devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */
devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */
#endif
struct device driverfs_dev_r[ST_NBR_MODES];
struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */
int partition;
......@@ -628,7 +629,7 @@ typedef struct {
unsigned char last_cmnd[6];
unsigned char last_sense[16];
#endif
struct gendisk *disk;
struct gendisk *drive;
} OS_Scsi_Tape;
/* Values of write_type */
......
......@@ -169,30 +169,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt);
/*
* Function: scsi_initialize_queue()
*
* Purpose: Selects queue handler function for a device.
* Purpose: Sets up the block queue for a device.
*
* Arguments: SDpnt - device for which we need a handler function.
*
* Returns: Nothing
*
* Lock status: No locking assumed or required.
*
* Notes: Most devices will end up using scsi_request_fn for the
* handler function (at least as things are done now).
* The "block" feature basically ensures that only one of
* the blocked hosts is active at one time, mainly to work around
* buggy DMA chipsets where the memory gets starved.
* For this case, we have a special handler function, which
* does some checks and ultimately calls scsi_request_fn.
*
* The single_lun feature is a similar special case.
*
* We handle these things by stacking the handlers. The
* special case handlers simply check a few conditions,
* and return if they are not supposed to do anything.
* In the event that things are OK, then they call the next
* handler in the list - ultimately they call scsi_request_fn
* to do the dirty deed.
*/
void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt)
{
......@@ -793,7 +776,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
rtn = host->hostt->queuecommand(SCpnt, scsi_done);
spin_unlock_irqrestore(host->host_lock, flags);
if (rtn != 0) {
scsi_delete_timer(SCpnt);
scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY);
SCSI_LOG_MLQUEUE(3,
printk("queuecommand : request rejected\n"));
......
......@@ -509,9 +509,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *);
/*
* 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 *);
extern int scsi_add_single_device(uint, uint, uint, uint);
extern int scsi_remove_single_device(uint, uint, uint, uint);
......
......@@ -7,18 +7,15 @@
* of people at Linux Expo.
*/
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/kernel.h>
#include <linux/blk.h>
#include <asm/hardirq.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_ioctl.h>
/*
* Function: scsi_insert_special_cmd()
......@@ -665,7 +662,7 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt)
{
struct request *req = SCpnt->request;
struct scatterlist *sgpnt;
int count, gfp_mask, ret = 0;
int count, ret = 0;
/*
* if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
......@@ -685,16 +682,10 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt)
*/
SCpnt->use_sg = req->nr_phys_segments;
gfp_mask = GFP_NOIO;
if (likely(in_atomic())) {
gfp_mask &= ~__GFP_WAIT;
gfp_mask |= __GFP_HIGH;
}
/*
* if sg table allocation fails, requeue request later.
*/
sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask);
sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC);
if (unlikely(!sgpnt)) {
req->flags |= REQ_SPECIAL;
ret = BLKPREP_DEFER;
......
......@@ -472,8 +472,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Return value:
* Scsi_Device pointer, or NULL on failure.
**/
struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
uint id, uint lun)
static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint channel, uint id, uint lun)
{
struct scsi_device *sdev, *device;
......@@ -542,7 +542,7 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
* Undo the actions in scsi_alloc_sdev, including removing @sdev from
* the list, and freeing @sdev.
**/
void scsi_free_sdev(struct scsi_device *sdev)
static void scsi_free_sdev(struct scsi_device *sdev)
{
list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings);
......@@ -1419,6 +1419,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
return SCSI_SCAN_LUN_PRESENT;
}
static int scsi_remove_lun(struct scsi_device *sdev)
{
devfs_unregister(sdev->de);
device_unregister(&sdev->sdev_driverfs_dev);
scsi_free_sdev(sdev);
}
/**
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
* @sdevscan: probe the LUN corresponding to this Scsi_Device
......@@ -1941,8 +1949,7 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
if (sdev->attached)
goto out;
devfs_unregister(sdev->de);
scsi_free_sdev(sdev);
scsi_remove_lun(sdev);
error = 0;
out:
......@@ -2068,3 +2075,69 @@ void scsi_scan_host(struct Scsi_Host *shost)
}
scsi_free_sdev(sdevscan);
}
void scsi_forget_host(struct Scsi_Host *shost)
{
struct list_head *le, *lh;
list_for_each_safe(le, lh, &shost->my_devices)
scsi_remove_lun(list_entry(le, struct scsi_device, siblings));
}
/*
* 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.
*
* 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);
}
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