You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-2.6.34' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.34' of git://git.kernel.dk/linux-2.6-block: (38 commits) block: don't access jiffies when initialising io_context cfq: remove 8 bytes of padding from cfq_rb_root on 64 bit builds block: fix for "Consolidate phys_segment and hw_segment limits" cfq-iosched: quantum check tweak blktrace: perform cleanup after setup error blkdev: fix merge_bvec_fn return value checks cfq-iosched: requests "in flight" vs "in driver" clarification cciss: Fix problem with scatter gather elements in the scsi half of the driver cciss: eliminate unnecessary pointer use in cciss scsi code cciss: do not use void pointer for scsi hba data cciss: factor out scatter gather chain block mapping code cciss: fix scatter gather chain block dma direction kludge cciss: simplify scatter gather code cciss: factor out scatter gather chain block allocation and freeing cciss: detect bad alignment of scsi commands at build time cciss: clarify command list padding calculation cfq-iosched: rethink seeky detection for SSDs cfq-iosched: rework seeky detection block: remove padding from io_context on 64bit builds block: Consolidate phys_segment and hw_segment limits ...
This commit is contained in:
@@ -128,3 +128,17 @@ Description:
|
||||
preferred request size for workloads where sustained
|
||||
throughput is desired. If no optimal I/O size is
|
||||
reported this file contains 0.
|
||||
|
||||
What: /sys/block/<disk>/queue/nomerges
|
||||
Date: January 2010
|
||||
Contact:
|
||||
Description:
|
||||
Standard I/O elevator operations include attempts to
|
||||
merge contiguous I/Os. For known random I/O loads these
|
||||
attempts will always fail and result in extra cycles
|
||||
being spent in the kernel. This allows one to turn off
|
||||
this behavior on one of two ways: When set to 1, complex
|
||||
merge checks are disabled, but the simple one-shot merges
|
||||
with the previous I/O request are enabled. When set to 2,
|
||||
all merge tries are disabled. The default value is 0 -
|
||||
which enables all types of merge tries.
|
||||
|
||||
@@ -25,11 +25,11 @@ size allowed by the hardware.
|
||||
|
||||
nomerges (RW)
|
||||
-------------
|
||||
This enables the user to disable the lookup logic involved with IO merging
|
||||
requests in the block layer. Merging may still occur through a direct
|
||||
1-hit cache, since that comes for (almost) free. The IO scheduler will not
|
||||
waste cycles doing tree/hash lookups for merges if nomerges is 1. Defaults
|
||||
to 0, enabling all merges.
|
||||
This enables the user to disable the lookup logic involved with IO
|
||||
merging requests in the block layer. By default (0) all merges are
|
||||
enabled. When set to 1 only simple one-hit merges will be tried. When
|
||||
set to 2 no merge algorithms will be tried (including one-hit or more
|
||||
complex tree/hash lookups).
|
||||
|
||||
nr_requests (RW)
|
||||
----------------
|
||||
|
||||
@@ -747,7 +747,7 @@ static int ubd_open_dev(struct ubd *ubd_dev)
|
||||
ubd_dev->fd = fd;
|
||||
|
||||
if(ubd_dev->cow.file != NULL){
|
||||
blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
|
||||
blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
|
||||
|
||||
err = -ENOMEM;
|
||||
ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
|
||||
@@ -849,7 +849,7 @@ static int ubd_add(int n, char **error_out)
|
||||
}
|
||||
ubd_dev->queue->queuedata = ubd_dev;
|
||||
|
||||
blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
|
||||
blk_queue_max_segments(ubd_dev->queue, MAX_SG);
|
||||
err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
|
||||
if(err){
|
||||
*error_out = "Failed to register device";
|
||||
|
||||
@@ -23,20 +23,6 @@ static LIST_HEAD(blkio_list);
|
||||
struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
|
||||
EXPORT_SYMBOL_GPL(blkio_root_cgroup);
|
||||
|
||||
bool blkiocg_css_tryget(struct blkio_cgroup *blkcg)
|
||||
{
|
||||
if (!css_tryget(&blkcg->css))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkiocg_css_tryget);
|
||||
|
||||
void blkiocg_css_put(struct blkio_cgroup *blkcg)
|
||||
{
|
||||
css_put(&blkcg->css);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkiocg_css_put);
|
||||
|
||||
struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup)
|
||||
{
|
||||
return container_of(cgroup_subsys_state(cgroup, blkio_subsys_id),
|
||||
|
||||
@@ -43,9 +43,6 @@ struct blkio_group {
|
||||
unsigned long sectors;
|
||||
};
|
||||
|
||||
extern bool blkiocg_css_tryget(struct blkio_cgroup *blkcg);
|
||||
extern void blkiocg_css_put(struct blkio_cgroup *blkcg);
|
||||
|
||||
typedef void (blkio_unlink_group_fn) (void *key, struct blkio_group *blkg);
|
||||
typedef void (blkio_update_group_weight_fn) (struct blkio_group *blkg,
|
||||
unsigned int weight);
|
||||
|
||||
+15
-19
@@ -1490,9 +1490,9 @@ end_io:
|
||||
/*
|
||||
* We only want one ->make_request_fn to be active at a time,
|
||||
* else stack usage with stacked devices could be a problem.
|
||||
* So use current->bio_{list,tail} to keep a list of requests
|
||||
* So use current->bio_list to keep a list of requests
|
||||
* submited by a make_request_fn function.
|
||||
* current->bio_tail is also used as a flag to say if
|
||||
* current->bio_list is also used as a flag to say if
|
||||
* generic_make_request is currently active in this task or not.
|
||||
* If it is NULL, then no make_request is active. If it is non-NULL,
|
||||
* then a make_request is active, and new requests should be added
|
||||
@@ -1500,11 +1500,11 @@ end_io:
|
||||
*/
|
||||
void generic_make_request(struct bio *bio)
|
||||
{
|
||||
if (current->bio_tail) {
|
||||
struct bio_list bio_list_on_stack;
|
||||
|
||||
if (current->bio_list) {
|
||||
/* make_request is active */
|
||||
*(current->bio_tail) = bio;
|
||||
bio->bi_next = NULL;
|
||||
current->bio_tail = &bio->bi_next;
|
||||
bio_list_add(current->bio_list, bio);
|
||||
return;
|
||||
}
|
||||
/* following loop may be a bit non-obvious, and so deserves some
|
||||
@@ -1512,30 +1512,27 @@ void generic_make_request(struct bio *bio)
|
||||
* Before entering the loop, bio->bi_next is NULL (as all callers
|
||||
* ensure that) so we have a list with a single bio.
|
||||
* We pretend that we have just taken it off a longer list, so
|
||||
* we assign bio_list to the next (which is NULL) and bio_tail
|
||||
* to &bio_list, thus initialising the bio_list of new bios to be
|
||||
* we assign bio_list to a pointer to the bio_list_on_stack,
|
||||
* thus initialising the bio_list of new bios to be
|
||||
* added. __generic_make_request may indeed add some more bios
|
||||
* through a recursive call to generic_make_request. If it
|
||||
* did, we find a non-NULL value in bio_list and re-enter the loop
|
||||
* from the top. In this case we really did just take the bio
|
||||
* of the top of the list (no pretending) and so fixup bio_list and
|
||||
* bio_tail or bi_next, and call into __generic_make_request again.
|
||||
* of the top of the list (no pretending) and so remove it from
|
||||
* bio_list, and call into __generic_make_request again.
|
||||
*
|
||||
* The loop was structured like this to make only one call to
|
||||
* __generic_make_request (which is important as it is large and
|
||||
* inlined) and to keep the structure simple.
|
||||
*/
|
||||
BUG_ON(bio->bi_next);
|
||||
bio_list_init(&bio_list_on_stack);
|
||||
current->bio_list = &bio_list_on_stack;
|
||||
do {
|
||||
current->bio_list = bio->bi_next;
|
||||
if (bio->bi_next == NULL)
|
||||
current->bio_tail = ¤t->bio_list;
|
||||
else
|
||||
bio->bi_next = NULL;
|
||||
__generic_make_request(bio);
|
||||
bio = current->bio_list;
|
||||
bio = bio_list_pop(current->bio_list);
|
||||
} while (bio);
|
||||
current->bio_tail = NULL; /* deactivate */
|
||||
current->bio_list = NULL; /* deactivate */
|
||||
}
|
||||
EXPORT_SYMBOL(generic_make_request);
|
||||
|
||||
@@ -1617,8 +1614,7 @@ int blk_rq_check_limits(struct request_queue *q, struct request *rq)
|
||||
* limitation.
|
||||
*/
|
||||
blk_recalc_rq_segments(rq);
|
||||
if (rq->nr_phys_segments > queue_max_phys_segments(q) ||
|
||||
rq->nr_phys_segments > queue_max_hw_segments(q)) {
|
||||
if (rq->nr_phys_segments > queue_max_segments(q)) {
|
||||
printk(KERN_ERR "%s: over max segments limit.\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
|
||||
spin_lock_init(&ret->lock);
|
||||
ret->ioprio_changed = 0;
|
||||
ret->ioprio = 0;
|
||||
ret->last_waited = jiffies; /* doesn't matter... */
|
||||
ret->last_waited = 0; /* doesn't matter... */
|
||||
ret->nr_batch_requests = 0; /* because this is 0 */
|
||||
INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
|
||||
INIT_HLIST_HEAD(&ret->cic_list);
|
||||
|
||||
+2
-6
@@ -206,8 +206,7 @@ static inline int ll_new_hw_segment(struct request_queue *q,
|
||||
{
|
||||
int nr_phys_segs = bio_phys_segments(q, bio);
|
||||
|
||||
if (req->nr_phys_segments + nr_phys_segs > queue_max_hw_segments(q) ||
|
||||
req->nr_phys_segments + nr_phys_segs > queue_max_phys_segments(q)) {
|
||||
if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) {
|
||||
req->cmd_flags |= REQ_NOMERGE;
|
||||
if (req == q->last_merge)
|
||||
q->last_merge = NULL;
|
||||
@@ -300,10 +299,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
|
||||
total_phys_segments--;
|
||||
}
|
||||
|
||||
if (total_phys_segments > queue_max_phys_segments(q))
|
||||
return 0;
|
||||
|
||||
if (total_phys_segments > queue_max_hw_segments(q))
|
||||
if (total_phys_segments > queue_max_segments(q))
|
||||
return 0;
|
||||
|
||||
/* Merge is OK... */
|
||||
|
||||
+42
-89
@@ -91,10 +91,9 @@ EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
|
||||
*/
|
||||
void blk_set_default_limits(struct queue_limits *lim)
|
||||
{
|
||||
lim->max_phys_segments = MAX_PHYS_SEGMENTS;
|
||||
lim->max_hw_segments = MAX_HW_SEGMENTS;
|
||||
lim->max_segments = BLK_MAX_SEGMENTS;
|
||||
lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
|
||||
lim->max_segment_size = MAX_SEGMENT_SIZE;
|
||||
lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
|
||||
lim->max_sectors = BLK_DEF_MAX_SECTORS;
|
||||
lim->max_hw_sectors = INT_MAX;
|
||||
lim->max_discard_sectors = 0;
|
||||
@@ -154,7 +153,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
|
||||
q->unplug_timer.data = (unsigned long)q;
|
||||
|
||||
blk_set_default_limits(&q->limits);
|
||||
blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
|
||||
blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
|
||||
|
||||
/*
|
||||
* If the caller didn't supply a lock, fall back to our embedded
|
||||
@@ -210,37 +209,32 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
|
||||
EXPORT_SYMBOL(blk_queue_bounce_limit);
|
||||
|
||||
/**
|
||||
* blk_queue_max_sectors - set max sectors for a request for this queue
|
||||
* blk_queue_max_hw_sectors - set max sectors for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* @max_sectors: max sectors in the usual 512b unit
|
||||
* @max_hw_sectors: max hardware sectors in the usual 512b unit
|
||||
*
|
||||
* Description:
|
||||
* Enables a low level driver to set an upper limit on the size of
|
||||
* received requests.
|
||||
* Enables a low level driver to set a hard upper limit,
|
||||
* max_hw_sectors, on the size of requests. max_hw_sectors is set by
|
||||
* the device driver based upon the combined capabilities of I/O
|
||||
* controller and storage device.
|
||||
*
|
||||
* max_sectors is a soft limit imposed by the block layer for
|
||||
* filesystem type requests. This value can be overridden on a
|
||||
* per-device basis in /sys/block/<device>/queue/max_sectors_kb.
|
||||
* The soft limit can not exceed max_hw_sectors.
|
||||
**/
|
||||
void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
|
||||
{
|
||||
if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
|
||||
max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
|
||||
if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
|
||||
max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
|
||||
printk(KERN_INFO "%s: set to minimum %d\n",
|
||||
__func__, max_sectors);
|
||||
__func__, max_hw_sectors);
|
||||
}
|
||||
|
||||
if (BLK_DEF_MAX_SECTORS > max_sectors)
|
||||
q->limits.max_hw_sectors = q->limits.max_sectors = max_sectors;
|
||||
else {
|
||||
q->limits.max_sectors = BLK_DEF_MAX_SECTORS;
|
||||
q->limits.max_hw_sectors = max_sectors;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_sectors);
|
||||
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
|
||||
{
|
||||
if (BLK_DEF_MAX_SECTORS > max_sectors)
|
||||
q->limits.max_hw_sectors = BLK_DEF_MAX_SECTORS;
|
||||
else
|
||||
q->limits.max_hw_sectors = max_sectors;
|
||||
q->limits.max_hw_sectors = max_hw_sectors;
|
||||
q->limits.max_sectors = min_t(unsigned int, max_hw_sectors,
|
||||
BLK_DEF_MAX_SECTORS);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
|
||||
|
||||
@@ -257,17 +251,15 @@ void blk_queue_max_discard_sectors(struct request_queue *q,
|
||||
EXPORT_SYMBOL(blk_queue_max_discard_sectors);
|
||||
|
||||
/**
|
||||
* blk_queue_max_phys_segments - set max phys segments for a request for this queue
|
||||
* blk_queue_max_segments - set max hw segments for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* @max_segments: max number of segments
|
||||
*
|
||||
* Description:
|
||||
* Enables a low level driver to set an upper limit on the number of
|
||||
* physical data segments in a request. This would be the largest sized
|
||||
* scatter list the driver could handle.
|
||||
* hw data segments in a request.
|
||||
**/
|
||||
void blk_queue_max_phys_segments(struct request_queue *q,
|
||||
unsigned short max_segments)
|
||||
void blk_queue_max_segments(struct request_queue *q, unsigned short max_segments)
|
||||
{
|
||||
if (!max_segments) {
|
||||
max_segments = 1;
|
||||
@@ -275,33 +267,9 @@ void blk_queue_max_phys_segments(struct request_queue *q,
|
||||
__func__, max_segments);
|
||||
}
|
||||
|
||||
q->limits.max_phys_segments = max_segments;
|
||||
q->limits.max_segments = max_segments;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_phys_segments);
|
||||
|
||||
/**
|
||||
* blk_queue_max_hw_segments - set max hw segments for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* @max_segments: max number of segments
|
||||
*
|
||||
* Description:
|
||||
* Enables a low level driver to set an upper limit on the number of
|
||||
* hw data segments in a request. This would be the largest number of
|
||||
* address/length pairs the host adapter can actually give at once
|
||||
* to the device.
|
||||
**/
|
||||
void blk_queue_max_hw_segments(struct request_queue *q,
|
||||
unsigned short max_segments)
|
||||
{
|
||||
if (!max_segments) {
|
||||
max_segments = 1;
|
||||
printk(KERN_INFO "%s: set to minimum %d\n",
|
||||
__func__, max_segments);
|
||||
}
|
||||
|
||||
q->limits.max_hw_segments = max_segments;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_hw_segments);
|
||||
EXPORT_SYMBOL(blk_queue_max_segments);
|
||||
|
||||
/**
|
||||
* blk_queue_max_segment_size - set max segment size for blk_rq_map_sg
|
||||
@@ -507,7 +475,7 @@ static unsigned int lcm(unsigned int a, unsigned int b)
|
||||
* blk_stack_limits - adjust queue_limits for stacked devices
|
||||
* @t: the stacking driver limits (top device)
|
||||
* @b: the underlying queue limits (bottom, component device)
|
||||
* @offset: offset to beginning of data within component device
|
||||
* @start: first data sector within component device
|
||||
*
|
||||
* Description:
|
||||
* This function is used by stacking drivers like MD and DM to ensure
|
||||
@@ -525,10 +493,9 @@ static unsigned int lcm(unsigned int a, unsigned int b)
|
||||
* the alignment_offset is undefined.
|
||||
*/
|
||||
int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
|
||||
sector_t offset)
|
||||
sector_t start)
|
||||
{
|
||||
sector_t alignment;
|
||||
unsigned int top, bottom, ret = 0;
|
||||
unsigned int top, bottom, alignment, ret = 0;
|
||||
|
||||
t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
|
||||
t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
|
||||
@@ -537,18 +504,14 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
|
||||
t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
|
||||
b->seg_boundary_mask);
|
||||
|
||||
t->max_phys_segments = min_not_zero(t->max_phys_segments,
|
||||
b->max_phys_segments);
|
||||
|
||||
t->max_hw_segments = min_not_zero(t->max_hw_segments,
|
||||
b->max_hw_segments);
|
||||
t->max_segments = min_not_zero(t->max_segments, b->max_segments);
|
||||
|
||||
t->max_segment_size = min_not_zero(t->max_segment_size,
|
||||
b->max_segment_size);
|
||||
|
||||
t->misaligned |= b->misaligned;
|
||||
|
||||
alignment = queue_limit_alignment_offset(b, offset);
|
||||
alignment = queue_limit_alignment_offset(b, start);
|
||||
|
||||
/* Bottom device has different alignment. Check that it is
|
||||
* compatible with the current top alignment.
|
||||
@@ -611,11 +574,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
|
||||
|
||||
/* Discard alignment and granularity */
|
||||
if (b->discard_granularity) {
|
||||
unsigned int granularity = b->discard_granularity;
|
||||
offset &= granularity - 1;
|
||||
|
||||
alignment = (granularity + b->discard_alignment - offset)
|
||||
& (granularity - 1);
|
||||
alignment = queue_limit_discard_alignment(b, start);
|
||||
|
||||
if (t->discard_granularity != 0 &&
|
||||
t->discard_alignment != alignment) {
|
||||
@@ -657,7 +616,7 @@ int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
|
||||
|
||||
start += get_start_sect(bdev);
|
||||
|
||||
return blk_stack_limits(t, &bq->limits, start << 9);
|
||||
return blk_stack_limits(t, &bq->limits, start);
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_stack_limits);
|
||||
|
||||
@@ -668,9 +627,8 @@ EXPORT_SYMBOL(bdev_stack_limits);
|
||||
* @offset: offset to beginning of data within component device
|
||||
*
|
||||
* Description:
|
||||
* Merges the limits for two queues. Returns 0 if alignment
|
||||
* didn't change. Returns -1 if adding the bottom device caused
|
||||
* misalignment.
|
||||
* Merges the limits for a top level gendisk and a bottom level
|
||||
* block_device.
|
||||
*/
|
||||
void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
||||
sector_t offset)
|
||||
@@ -678,9 +636,7 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
||||
struct request_queue *t = disk->queue;
|
||||
struct request_queue *b = bdev_get_queue(bdev);
|
||||
|
||||
offset += get_start_sect(bdev) << 9;
|
||||
|
||||
if (blk_stack_limits(&t->limits, &b->limits, offset) < 0) {
|
||||
if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
|
||||
char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
|
||||
|
||||
disk_name(disk, 0, top);
|
||||
@@ -752,22 +708,19 @@ EXPORT_SYMBOL(blk_queue_update_dma_pad);
|
||||
* does is adjust the queue so that the buf is always appended
|
||||
* silently to the scatterlist.
|
||||
*
|
||||
* Note: This routine adjusts max_hw_segments to make room for
|
||||
* appending the drain buffer. If you call
|
||||
* blk_queue_max_hw_segments() or blk_queue_max_phys_segments() after
|
||||
* calling this routine, you must set the limit to one fewer than your
|
||||
* device can support otherwise there won't be room for the drain
|
||||
* buffer.
|
||||
* Note: This routine adjusts max_hw_segments to make room for appending
|
||||
* the drain buffer. If you call blk_queue_max_segments() after calling
|
||||
* this routine, you must set the limit to one fewer than your device
|
||||
* can support otherwise there won't be room for the drain buffer.
|
||||
*/
|
||||
int blk_queue_dma_drain(struct request_queue *q,
|
||||
dma_drain_needed_fn *dma_drain_needed,
|
||||
void *buf, unsigned int size)
|
||||
{
|
||||
if (queue_max_hw_segments(q) < 2 || queue_max_phys_segments(q) < 2)
|
||||
if (queue_max_segments(q) < 2)
|
||||
return -EINVAL;
|
||||
/* make room for appending the drain */
|
||||
blk_queue_max_hw_segments(q, queue_max_hw_segments(q) - 1);
|
||||
blk_queue_max_phys_segments(q, queue_max_phys_segments(q) - 1);
|
||||
blk_queue_max_segments(q, queue_max_segments(q) - 1);
|
||||
q->dma_drain_needed = dma_drain_needed;
|
||||
q->dma_drain_buffer = buf;
|
||||
q->dma_drain_size = size;
|
||||
|
||||
+7
-4
@@ -189,7 +189,8 @@ static ssize_t queue_nonrot_store(struct request_queue *q, const char *page,
|
||||
|
||||
static ssize_t queue_nomerges_show(struct request_queue *q, char *page)
|
||||
{
|
||||
return queue_var_show(blk_queue_nomerges(q), page);
|
||||
return queue_var_show((blk_queue_nomerges(q) << 1) |
|
||||
blk_queue_noxmerges(q), page);
|
||||
}
|
||||
|
||||
static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
|
||||
@@ -199,10 +200,12 @@ static ssize_t queue_nomerges_store(struct request_queue *q, const char *page,
|
||||
ssize_t ret = queue_var_store(&nm, page, count);
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
if (nm)
|
||||
queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
|
||||
queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
|
||||
if (nm == 2)
|
||||
queue_flag_set(QUEUE_FLAG_NOMERGES, q);
|
||||
else
|
||||
queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
|
||||
else if (nm)
|
||||
queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
|
||||
return ret;
|
||||
|
||||
+68
-79
@@ -19,7 +19,7 @@
|
||||
* tunables
|
||||
*/
|
||||
/* max queue in one round of service */
|
||||
static const int cfq_quantum = 4;
|
||||
static const int cfq_quantum = 8;
|
||||
static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
|
||||
/* maximum backwards seek, in KiB */
|
||||
static const int cfq_back_max = 16 * 1024;
|
||||
@@ -46,8 +46,9 @@ static const int cfq_hist_divisor = 4;
|
||||
#define CFQ_HW_QUEUE_MIN (5)
|
||||
#define CFQ_SERVICE_SHIFT 12
|
||||
|
||||
#define CFQQ_SEEK_THR 8 * 1024
|
||||
#define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR)
|
||||
#define CFQQ_SEEK_THR (sector_t)(8 * 100)
|
||||
#define CFQQ_SECT_THR_NONROT (sector_t)(2 * 32)
|
||||
#define CFQQ_SEEKY(cfqq) (hweight32(cfqq->seek_history) > 32/8)
|
||||
|
||||
#define RQ_CIC(rq) \
|
||||
((struct cfq_io_context *) (rq)->elevator_private)
|
||||
@@ -77,11 +78,12 @@ struct cfq_rb_root {
|
||||
struct rb_root rb;
|
||||
struct rb_node *left;
|
||||
unsigned count;
|
||||
unsigned total_weight;
|
||||
u64 min_vdisktime;
|
||||
struct rb_node *active;
|
||||
unsigned total_weight;
|
||||
};
|
||||
#define CFQ_RB_ROOT (struct cfq_rb_root) { RB_ROOT, NULL, 0, 0, }
|
||||
#define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT, .left = NULL, \
|
||||
.count = 0, .min_vdisktime = 0, }
|
||||
|
||||
/*
|
||||
* Per process-grouping structure
|
||||
@@ -115,11 +117,11 @@ struct cfq_queue {
|
||||
/* time when queue got scheduled in to dispatch first request. */
|
||||
unsigned long dispatch_start;
|
||||
unsigned int allocated_slice;
|
||||
unsigned int slice_dispatch;
|
||||
/* time when first request from queue completed and slice started. */
|
||||
unsigned long slice_start;
|
||||
unsigned long slice_end;
|
||||
long slice_resid;
|
||||
unsigned int slice_dispatch;
|
||||
|
||||
/* pending metadata requests */
|
||||
int meta_pending;
|
||||
@@ -130,13 +132,11 @@ struct cfq_queue {
|
||||
unsigned short ioprio, org_ioprio;
|
||||
unsigned short ioprio_class, org_ioprio_class;
|
||||
|
||||
unsigned int seek_samples;
|
||||
u64 seek_total;
|
||||
sector_t seek_mean;
|
||||
sector_t last_request_pos;
|
||||
|
||||
pid_t pid;
|
||||
|
||||
u32 seek_history;
|
||||
sector_t last_request_pos;
|
||||
|
||||
struct cfq_rb_root *service_tree;
|
||||
struct cfq_queue *new_cfqq;
|
||||
struct cfq_group *cfqg;
|
||||
@@ -223,8 +223,8 @@ struct cfq_data {
|
||||
|
||||
unsigned int busy_queues;
|
||||
|
||||
int rq_in_driver[2];
|
||||
int sync_flight;
|
||||
int rq_in_driver;
|
||||
int rq_in_flight[2];
|
||||
|
||||
/*
|
||||
* queue-depth detection
|
||||
@@ -417,11 +417,6 @@ static struct cfq_queue *cfq_get_queue(struct cfq_data *, bool,
|
||||
static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
|
||||
struct io_context *);
|
||||
|
||||
static inline int rq_in_driver(struct cfq_data *cfqd)
|
||||
{
|
||||
return cfqd->rq_in_driver[0] + cfqd->rq_in_driver[1];
|
||||
}
|
||||
|
||||
static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
|
||||
bool is_sync)
|
||||
{
|
||||
@@ -951,10 +946,6 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
|
||||
struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info;
|
||||
unsigned int major, minor;
|
||||
|
||||
/* Do we need to take this reference */
|
||||
if (!blkiocg_css_tryget(blkcg))
|
||||
return NULL;;
|
||||
|
||||
cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
|
||||
if (cfqg || !create)
|
||||
goto done;
|
||||
@@ -985,7 +976,6 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
|
||||
hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
|
||||
|
||||
done:
|
||||
blkiocg_css_put(blkcg);
|
||||
return cfqg;
|
||||
}
|
||||
|
||||
@@ -1420,9 +1410,9 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
|
||||
{
|
||||
struct cfq_data *cfqd = q->elevator->elevator_data;
|
||||
|
||||
cfqd->rq_in_driver[rq_is_sync(rq)]++;
|
||||
cfqd->rq_in_driver++;
|
||||
cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
|
||||
rq_in_driver(cfqd));
|
||||
cfqd->rq_in_driver);
|
||||
|
||||
cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
|
||||
}
|
||||
@@ -1430,12 +1420,11 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
|
||||
static void cfq_deactivate_request(struct request_queue *q, struct request *rq)
|
||||
{
|
||||
struct cfq_data *cfqd = q->elevator->elevator_data;
|
||||
const int sync = rq_is_sync(rq);
|
||||
|
||||
WARN_ON(!cfqd->rq_in_driver[sync]);
|
||||
cfqd->rq_in_driver[sync]--;
|
||||
WARN_ON(!cfqd->rq_in_driver);
|
||||
cfqd->rq_in_driver--;
|
||||
cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d",
|
||||
rq_in_driver(cfqd));
|
||||
cfqd->rq_in_driver);
|
||||
}
|
||||
|
||||
static void cfq_remove_request(struct request *rq)
|
||||
@@ -1673,16 +1662,7 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
|
||||
static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
||||
struct request *rq, bool for_preempt)
|
||||
{
|
||||
sector_t sdist = cfqq->seek_mean;
|
||||
|
||||
if (!sample_valid(cfqq->seek_samples))
|
||||
sdist = CFQQ_SEEK_THR;
|
||||
|
||||
/* if seek_mean is big, using it as close criteria is meaningless */
|
||||
if (sdist > CFQQ_SEEK_THR && !for_preempt)
|
||||
sdist = CFQQ_SEEK_THR;
|
||||
|
||||
return cfq_dist_from_last(cfqd, rq) <= sdist;
|
||||
return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR;
|
||||
}
|
||||
|
||||
static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
|
||||
@@ -1878,8 +1858,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
|
||||
cfqq->dispatched++;
|
||||
elv_dispatch_sort(q, rq);
|
||||
|
||||
if (cfq_cfqq_sync(cfqq))
|
||||
cfqd->sync_flight++;
|
||||
cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]++;
|
||||
cfqq->nr_sectors += blk_rq_sectors(rq);
|
||||
}
|
||||
|
||||
@@ -2219,6 +2198,19 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
|
||||
return dispatched;
|
||||
}
|
||||
|
||||
static inline bool cfq_slice_used_soon(struct cfq_data *cfqd,
|
||||
struct cfq_queue *cfqq)
|
||||
{
|
||||
/* the queue hasn't finished any request, can't estimate */
|
||||
if (cfq_cfqq_slice_new(cfqq))
|
||||
return 1;
|
||||
if (time_after(jiffies + cfqd->cfq_slice_idle * cfqq->dispatched,
|
||||
cfqq->slice_end))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
|
||||
{
|
||||
unsigned int max_dispatch;
|
||||
@@ -2226,16 +2218,16 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
|
||||
/*
|
||||
* Drain async requests before we start sync IO
|
||||
*/
|
||||
if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
|
||||
if (cfq_should_idle(cfqd, cfqq) && cfqd->rq_in_flight[BLK_RW_ASYNC])
|
||||
return false;
|
||||
|
||||
/*
|
||||
* If this is an async queue and we have sync IO in flight, let it wait
|
||||
*/
|
||||
if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
|
||||
if (cfqd->rq_in_flight[BLK_RW_SYNC] && !cfq_cfqq_sync(cfqq))
|
||||
return false;
|
||||
|
||||
max_dispatch = cfqd->cfq_quantum;
|
||||
max_dispatch = max_t(unsigned int, cfqd->cfq_quantum / 2, 1);
|
||||
if (cfq_class_idle(cfqq))
|
||||
max_dispatch = 1;
|
||||
|
||||
@@ -2252,13 +2244,22 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
|
||||
/*
|
||||
* We have other queues, don't allow more IO from this one
|
||||
*/
|
||||
if (cfqd->busy_queues > 1)
|
||||
if (cfqd->busy_queues > 1 && cfq_slice_used_soon(cfqd, cfqq))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Sole queue user, no limit
|
||||
*/
|
||||
max_dispatch = -1;
|
||||
if (cfqd->busy_queues == 1)
|
||||
max_dispatch = -1;
|
||||
else
|
||||
/*
|
||||
* Normally we start throttling cfqq when cfq_quantum/2
|
||||
* requests have been dispatched. But we can drive
|
||||
* deeper queue depths at the beginning of slice
|
||||
* subjected to upper limit of cfq_quantum.
|
||||
* */
|
||||
max_dispatch = cfqd->cfq_quantum;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2980,30 +2981,20 @@ static void
|
||||
cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
||||
struct request *rq)
|
||||
{
|
||||
sector_t sdist;
|
||||
u64 total;
|
||||
sector_t sdist = 0;
|
||||
sector_t n_sec = blk_rq_sectors(rq);
|
||||
if (cfqq->last_request_pos) {
|
||||
if (cfqq->last_request_pos < blk_rq_pos(rq))
|
||||
sdist = blk_rq_pos(rq) - cfqq->last_request_pos;
|
||||
else
|
||||
sdist = cfqq->last_request_pos - blk_rq_pos(rq);
|
||||
}
|
||||
|
||||
if (!cfqq->last_request_pos)
|
||||
sdist = 0;
|
||||
else if (cfqq->last_request_pos < blk_rq_pos(rq))
|
||||
sdist = blk_rq_pos(rq) - cfqq->last_request_pos;
|
||||
cfqq->seek_history <<= 1;
|
||||
if (blk_queue_nonrot(cfqd->queue))
|
||||
cfqq->seek_history |= (n_sec < CFQQ_SECT_THR_NONROT);
|
||||
else
|
||||
sdist = cfqq->last_request_pos - blk_rq_pos(rq);
|
||||
|
||||
/*
|
||||
* Don't allow the seek distance to get too large from the
|
||||
* odd fragment, pagein, etc
|
||||
*/
|
||||
if (cfqq->seek_samples <= 60) /* second&third seek */
|
||||
sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*1024);
|
||||
else
|
||||
sdist = min(sdist, (cfqq->seek_mean * 4) + 2*1024*64);
|
||||
|
||||
cfqq->seek_samples = (7*cfqq->seek_samples + 256) / 8;
|
||||
cfqq->seek_total = (7*cfqq->seek_total + (u64)256*sdist) / 8;
|
||||
total = cfqq->seek_total + (cfqq->seek_samples/2);
|
||||
do_div(total, cfqq->seek_samples);
|
||||
cfqq->seek_mean = (sector_t)total;
|
||||
cfqq->seek_history |= (sdist > CFQQ_SEEK_THR);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3028,8 +3019,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
|
||||
cfq_mark_cfqq_deep(cfqq);
|
||||
|
||||
if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
|
||||
(!cfq_cfqq_deep(cfqq) && sample_valid(cfqq->seek_samples)
|
||||
&& CFQQ_SEEKY(cfqq)))
|
||||
(!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
|
||||
enable_idle = 0;
|
||||
else if (sample_valid(cic->ttime_samples)) {
|
||||
if (cic->ttime_mean > cfqd->cfq_slice_idle)
|
||||
@@ -3215,14 +3205,14 @@ static void cfq_update_hw_tag(struct cfq_data *cfqd)
|
||||
{
|
||||
struct cfq_queue *cfqq = cfqd->active_queue;
|
||||
|
||||
if (rq_in_driver(cfqd) > cfqd->hw_tag_est_depth)
|
||||
cfqd->hw_tag_est_depth = rq_in_driver(cfqd);
|
||||
if (cfqd->rq_in_driver > cfqd->hw_tag_est_depth)
|
||||
cfqd->hw_tag_est_depth = cfqd->rq_in_driver;
|
||||
|
||||
if (cfqd->hw_tag == 1)
|
||||
return;
|
||||
|
||||
if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN &&
|
||||
rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN)
|
||||
cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN)
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -3232,7 +3222,7 @@ static void cfq_update_hw_tag(struct cfq_data *cfqd)
|
||||
*/
|
||||
if (cfqq && cfq_cfqq_idle_window(cfqq) &&
|
||||
cfqq->dispatched + cfqq->queued[0] + cfqq->queued[1] <
|
||||
CFQ_HW_QUEUE_MIN && rq_in_driver(cfqd) < CFQ_HW_QUEUE_MIN)
|
||||
CFQ_HW_QUEUE_MIN && cfqd->rq_in_driver < CFQ_HW_QUEUE_MIN)
|
||||
return;
|
||||
|
||||
if (cfqd->hw_tag_samples++ < 50)
|
||||
@@ -3285,13 +3275,12 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
|
||||
|
||||
cfq_update_hw_tag(cfqd);
|
||||
|
||||
WARN_ON(!cfqd->rq_in_driver[sync]);
|
||||
WARN_ON(!cfqd->rq_in_driver);
|
||||
WARN_ON(!cfqq->dispatched);
|
||||
cfqd->rq_in_driver[sync]--;
|
||||
cfqd->rq_in_driver--;
|
||||
cfqq->dispatched--;
|
||||
|
||||
if (cfq_cfqq_sync(cfqq))
|
||||
cfqd->sync_flight--;
|
||||
cfqd->rq_in_flight[cfq_cfqq_sync(cfqq)]--;
|
||||
|
||||
if (sync) {
|
||||
RQ_CIC(rq)->last_end_request = now;
|
||||
@@ -3345,7 +3334,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
|
||||
}
|
||||
}
|
||||
|
||||
if (!rq_in_driver(cfqd))
|
||||
if (!cfqd->rq_in_driver)
|
||||
cfq_schedule_dispatch(cfqd);
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -473,6 +473,15 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
struct request *__rq;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Levels of merges:
|
||||
* nomerges: No merges at all attempted
|
||||
* noxmerges: Only simple one-hit cache try
|
||||
* merges: All merge tries attempted
|
||||
*/
|
||||
if (blk_queue_nomerges(q))
|
||||
return ELEVATOR_NO_MERGE;
|
||||
|
||||
/*
|
||||
* First try one-hit cache.
|
||||
*/
|
||||
@@ -484,7 +493,7 @@ int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
|
||||
}
|
||||
}
|
||||
|
||||
if (blk_queue_nomerges(q))
|
||||
if (blk_queue_noxmerges(q))
|
||||
return ELEVATOR_NO_MERGE;
|
||||
|
||||
/*
|
||||
|
||||
@@ -1097,7 +1097,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
|
||||
dev->flags |= ATA_DFLAG_NO_UNLOAD;
|
||||
|
||||
/* configure max sectors */
|
||||
blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
|
||||
blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors);
|
||||
|
||||
if (dev->class == ATA_DEV_ATAPI) {
|
||||
struct request_queue *q = sdev->request_queue;
|
||||
|
||||
@@ -772,7 +772,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
|
||||
}
|
||||
|
||||
blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
|
||||
blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
|
||||
blk_queue_max_segments(sdev->request_queue, sg_tablesize);
|
||||
ata_port_printk(ap, KERN_INFO,
|
||||
"DMA mask 0x%llX, segment boundary 0x%lX, hw segs %hu\n",
|
||||
(unsigned long long)*ap->host->dev->dma_mask,
|
||||
|
||||
@@ -2534,8 +2534,8 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
|
||||
blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
|
||||
RequestQueue->queuedata = Controller;
|
||||
blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
|
||||
blk_queue_max_phys_segments(RequestQueue, Controller->DriverScatterGatherLimit);
|
||||
blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
|
||||
blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
|
||||
blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
|
||||
disk->queue = RequestQueue;
|
||||
sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
|
||||
disk->major = MajorNumber;
|
||||
@@ -7134,7 +7134,7 @@ static struct DAC960_privdata DAC960_P_privdata = {
|
||||
.MemoryWindowSize = DAC960_PD_RegisterWindowSize,
|
||||
};
|
||||
|
||||
static struct pci_device_id DAC960_id_table[] = {
|
||||
static const struct pci_device_id DAC960_id_table[] = {
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_MYLEX,
|
||||
.device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
|
||||
|
||||
+1
-1
@@ -434,7 +434,7 @@ static struct brd_device *brd_alloc(int i)
|
||||
goto out_free_dev;
|
||||
blk_queue_make_request(brd->brd_queue, brd_make_request);
|
||||
blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL);
|
||||
blk_queue_max_sectors(brd->brd_queue, 1024);
|
||||
blk_queue_max_hw_sectors(brd->brd_queue, 1024);
|
||||
blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY);
|
||||
|
||||
disk = brd->brd_disk = alloc_disk(1 << part_shift);
|
||||
|
||||
+107
-111
@@ -257,6 +257,79 @@ static inline void removeQ(CommandList_struct *c)
|
||||
hlist_del_init(&c->list);
|
||||
}
|
||||
|
||||
static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list,
|
||||
int nr_cmds)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!cmd_sg_list)
|
||||
return;
|
||||
for (i = 0; i < nr_cmds; i++) {
|
||||
kfree(cmd_sg_list[i]);
|
||||
cmd_sg_list[i] = NULL;
|
||||
}
|
||||
kfree(cmd_sg_list);
|
||||
}
|
||||
|
||||
static SGDescriptor_struct **cciss_allocate_sg_chain_blocks(
|
||||
ctlr_info_t *h, int chainsize, int nr_cmds)
|
||||
{
|
||||
int j;
|
||||
SGDescriptor_struct **cmd_sg_list;
|
||||
|
||||
if (chainsize <= 0)
|
||||
return NULL;
|
||||
|
||||
cmd_sg_list = kmalloc(sizeof(*cmd_sg_list) * nr_cmds, GFP_KERNEL);
|
||||
if (!cmd_sg_list)
|
||||
return NULL;
|
||||
|
||||
/* Build up chain blocks for each command */
|
||||
for (j = 0; j < nr_cmds; j++) {
|
||||
/* Need a block of chainsized s/g elements. */
|
||||
cmd_sg_list[j] = kmalloc((chainsize *
|
||||
sizeof(*cmd_sg_list[j])), GFP_KERNEL);
|
||||
if (!cmd_sg_list[j]) {
|
||||
dev_err(&h->pdev->dev, "Cannot get memory "
|
||||
"for s/g chains.\n");
|
||||
goto clean;
|
||||
}
|
||||
}
|
||||
return cmd_sg_list;
|
||||
clean:
|
||||
cciss_free_sg_chain_blocks(cmd_sg_list, nr_cmds);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void cciss_unmap_sg_chain_block(ctlr_info_t *h, CommandList_struct *c)
|
||||
{
|
||||
SGDescriptor_struct *chain_sg;
|
||||
u64bit temp64;
|
||||
|
||||
if (c->Header.SGTotal <= h->max_cmd_sgentries)
|
||||
return;
|
||||
|
||||
chain_sg = &c->SG[h->max_cmd_sgentries - 1];
|
||||
temp64.val32.lower = chain_sg->Addr.lower;
|
||||
temp64.val32.upper = chain_sg->Addr.upper;
|
||||
pci_unmap_single(h->pdev, temp64.val, chain_sg->Len, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
static void cciss_map_sg_chain_block(ctlr_info_t *h, CommandList_struct *c,
|
||||
SGDescriptor_struct *chain_block, int len)
|
||||
{
|
||||
SGDescriptor_struct *chain_sg;
|
||||
u64bit temp64;
|
||||
|
||||
chain_sg = &c->SG[h->max_cmd_sgentries - 1];
|
||||
chain_sg->Ext = CCISS_SG_CHAIN;
|
||||
chain_sg->Len = len;
|
||||
temp64.val = pci_map_single(h->pdev, chain_block, len,
|
||||
PCI_DMA_TODEVICE);
|
||||
chain_sg->Addr.lower = temp64.val32.lower;
|
||||
chain_sg->Addr.upper = temp64.val32.upper;
|
||||
}
|
||||
|
||||
#include "cciss_scsi.c" /* For SCSI tape support */
|
||||
|
||||
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
|
||||
@@ -1344,26 +1417,27 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
kfree(buff);
|
||||
return -ENOMEM;
|
||||
}
|
||||
// Fill in the command type
|
||||
/* Fill in the command type */
|
||||
c->cmd_type = CMD_IOCTL_PEND;
|
||||
// Fill in Command Header
|
||||
c->Header.ReplyQueue = 0; // unused in simple mode
|
||||
if (iocommand.buf_size > 0) // buffer to fill
|
||||
/* Fill in Command Header */
|
||||
c->Header.ReplyQueue = 0; /* unused in simple mode */
|
||||
if (iocommand.buf_size > 0) /* buffer to fill */
|
||||
{
|
||||
c->Header.SGList = 1;
|
||||
c->Header.SGTotal = 1;
|
||||
} else // no buffers to fill
|
||||
} else /* no buffers to fill */
|
||||
{
|
||||
c->Header.SGList = 0;
|
||||
c->Header.SGTotal = 0;
|
||||
}
|
||||
c->Header.LUN = iocommand.LUN_info;
|
||||
c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag
|
||||
/* use the kernel address the cmd block for tag */
|
||||
c->Header.Tag.lower = c->busaddr;
|
||||
|
||||
// Fill in Request block
|
||||
/* Fill in Request block */
|
||||
c->Request = iocommand.Request;
|
||||
|
||||
// Fill in the scatter gather information
|
||||
/* Fill in the scatter gather information */
|
||||
if (iocommand.buf_size > 0) {
|
||||
temp64.val = pci_map_single(host->pdev, buff,
|
||||
iocommand.buf_size,
|
||||
@@ -1371,7 +1445,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
|
||||
c->SG[0].Addr.lower = temp64.val32.lower;
|
||||
c->SG[0].Addr.upper = temp64.val32.upper;
|
||||
c->SG[0].Len = iocommand.buf_size;
|
||||
c->SG[0].Ext = 0; // we are not chaining
|
||||
c->SG[0].Ext = 0; /* we are not chaining */
|
||||
}
|
||||
c->waiting = &wait;
|
||||
|
||||
@@ -1670,14 +1744,9 @@ static void cciss_softirq_done(struct request *rq)
|
||||
/* unmap the DMA mapping for all the scatter gather elements */
|
||||
for (i = 0; i < cmd->Header.SGList; i++) {
|
||||
if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) {
|
||||
temp64.val32.lower = cmd->SG[i].Addr.lower;
|
||||
temp64.val32.upper = cmd->SG[i].Addr.upper;
|
||||
pci_dma_sync_single_for_cpu(h->pdev, temp64.val,
|
||||
cmd->SG[i].Len, ddir);
|
||||
pci_unmap_single(h->pdev, temp64.val,
|
||||
cmd->SG[i].Len, ddir);
|
||||
cciss_unmap_sg_chain_block(h, cmd);
|
||||
/* Point to the next block */
|
||||
curr_sg = h->cmd_sg_list[cmd->cmdindex]->sgchain;
|
||||
curr_sg = h->cmd_sg_list[cmd->cmdindex];
|
||||
sg_index = 0;
|
||||
}
|
||||
temp64.val32.lower = curr_sg[sg_index].Addr.lower;
|
||||
@@ -1796,12 +1865,9 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
|
||||
blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
|
||||
|
||||
/* This is a hardware imposed limit. */
|
||||
blk_queue_max_hw_segments(disk->queue, h->maxsgentries);
|
||||
blk_queue_max_segments(disk->queue, h->maxsgentries);
|
||||
|
||||
/* This is a limit in the driver and could be eliminated. */
|
||||
blk_queue_max_phys_segments(disk->queue, h->maxsgentries);
|
||||
|
||||
blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
|
||||
blk_queue_max_hw_sectors(disk->queue, h->cciss_max_sectors);
|
||||
|
||||
blk_queue_softirq_done(disk->queue, cciss_softirq_done);
|
||||
|
||||
@@ -2425,7 +2491,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
|
||||
c->Request.Type.Direction = XFER_READ;
|
||||
c->Request.Timeout = 0;
|
||||
c->Request.CDB[0] = cmd;
|
||||
c->Request.CDB[6] = (size >> 24) & 0xFF; //MSB
|
||||
c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */
|
||||
c->Request.CDB[7] = (size >> 16) & 0xFF;
|
||||
c->Request.CDB[8] = (size >> 8) & 0xFF;
|
||||
c->Request.CDB[9] = size & 0xFF;
|
||||
@@ -2694,7 +2760,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
|
||||
"cciss: reading geometry failed, volume "
|
||||
"does not support reading geometry\n");
|
||||
drv->heads = 255;
|
||||
drv->sectors = 32; // Sectors per track
|
||||
drv->sectors = 32; /* Sectors per track */
|
||||
drv->cylinders = total_size + 1;
|
||||
drv->raid_level = RAID_UNKNOWN;
|
||||
} else {
|
||||
@@ -3082,7 +3148,6 @@ static void do_cciss_request(struct request_queue *q)
|
||||
SGDescriptor_struct *curr_sg;
|
||||
drive_info_struct *drv;
|
||||
int i, dir;
|
||||
int nseg = 0;
|
||||
int sg_index = 0;
|
||||
int chained = 0;
|
||||
|
||||
@@ -3112,19 +3177,19 @@ static void do_cciss_request(struct request_queue *q)
|
||||
|
||||
/* fill in the request */
|
||||
drv = creq->rq_disk->private_data;
|
||||
c->Header.ReplyQueue = 0; // unused in simple mode
|
||||
c->Header.ReplyQueue = 0; /* unused in simple mode */
|
||||
/* got command from pool, so use the command block index instead */
|
||||
/* for direct lookups. */
|
||||
/* The first 2 bits are reserved for controller error reporting. */
|
||||
c->Header.Tag.lower = (c->cmdindex << 3);
|
||||
c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
|
||||
memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
|
||||
c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
|
||||
c->Request.Type.Type = TYPE_CMD; // It is a command.
|
||||
c->Request.CDBLen = 10; /* 12 byte commands not in FW yet; */
|
||||
c->Request.Type.Type = TYPE_CMD; /* It is a command. */
|
||||
c->Request.Type.Attribute = ATTR_SIMPLE;
|
||||
c->Request.Type.Direction =
|
||||
(rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
|
||||
c->Request.Timeout = 0; // Don't time out
|
||||
c->Request.Timeout = 0; /* Don't time out */
|
||||
c->Request.CDB[0] =
|
||||
(rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
|
||||
start_blk = blk_rq_pos(creq);
|
||||
@@ -3149,13 +3214,8 @@ static void do_cciss_request(struct request_queue *q)
|
||||
for (i = 0; i < seg; i++) {
|
||||
if (((sg_index+1) == (h->max_cmd_sgentries)) &&
|
||||
!chained && ((seg - i) > 1)) {
|
||||
nseg = seg - i;
|
||||
curr_sg[sg_index].Len = (nseg) *
|
||||
sizeof(SGDescriptor_struct);
|
||||
curr_sg[sg_index].Ext = CCISS_SG_CHAIN;
|
||||
|
||||
/* Point to next chain block. */
|
||||
curr_sg = h->cmd_sg_list[c->cmdindex]->sgchain;
|
||||
curr_sg = h->cmd_sg_list[c->cmdindex];
|
||||
sg_index = 0;
|
||||
chained = 1;
|
||||
}
|
||||
@@ -3166,31 +3226,12 @@ static void do_cciss_request(struct request_queue *q)
|
||||
curr_sg[sg_index].Addr.lower = temp64.val32.lower;
|
||||
curr_sg[sg_index].Addr.upper = temp64.val32.upper;
|
||||
curr_sg[sg_index].Ext = 0; /* we are not chaining */
|
||||
|
||||
++sg_index;
|
||||
}
|
||||
|
||||
if (chained) {
|
||||
int len;
|
||||
curr_sg = c->SG;
|
||||
sg_index = h->max_cmd_sgentries - 1;
|
||||
len = curr_sg[sg_index].Len;
|
||||
/* Setup pointer to next chain block.
|
||||
* Fill out last element in current chain
|
||||
* block with address of next chain block.
|
||||
*/
|
||||
temp64.val = pci_map_single(h->pdev,
|
||||
h->cmd_sg_list[c->cmdindex]->sgchain,
|
||||
len, dir);
|
||||
|
||||
h->cmd_sg_list[c->cmdindex]->sg_chain_dma = temp64.val;
|
||||
curr_sg[sg_index].Addr.lower = temp64.val32.lower;
|
||||
curr_sg[sg_index].Addr.upper = temp64.val32.upper;
|
||||
|
||||
pci_dma_sync_single_for_device(h->pdev,
|
||||
h->cmd_sg_list[c->cmdindex]->sg_chain_dma,
|
||||
len, dir);
|
||||
}
|
||||
if (chained)
|
||||
cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
|
||||
(seg - (h->max_cmd_sgentries - 1)) *
|
||||
sizeof(SGDescriptor_struct));
|
||||
|
||||
/* track how many SG entries we are using */
|
||||
if (seg > h->maxSG)
|
||||
@@ -3209,11 +3250,11 @@ static void do_cciss_request(struct request_queue *q)
|
||||
if (likely(blk_fs_request(creq))) {
|
||||
if(h->cciss_read == CCISS_READ_10) {
|
||||
c->Request.CDB[1] = 0;
|
||||
c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
|
||||
c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */
|
||||
c->Request.CDB[3] = (start_blk >> 16) & 0xff;
|
||||
c->Request.CDB[4] = (start_blk >> 8) & 0xff;
|
||||
c->Request.CDB[5] = start_blk & 0xff;
|
||||
c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
|
||||
c->Request.CDB[6] = 0; /* (sect >> 24) & 0xff; MSB */
|
||||
c->Request.CDB[7] = (blk_rq_sectors(creq) >> 8) & 0xff;
|
||||
c->Request.CDB[8] = blk_rq_sectors(creq) & 0xff;
|
||||
c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
|
||||
@@ -3222,7 +3263,7 @@ static void do_cciss_request(struct request_queue *q)
|
||||
|
||||
c->Request.CDBLen = 16;
|
||||
c->Request.CDB[1]= 0;
|
||||
c->Request.CDB[2]= (upper32 >> 24) & 0xff; //MSB
|
||||
c->Request.CDB[2]= (upper32 >> 24) & 0xff; /* MSB */
|
||||
c->Request.CDB[3]= (upper32 >> 16) & 0xff;
|
||||
c->Request.CDB[4]= (upper32 >> 8) & 0xff;
|
||||
c->Request.CDB[5]= upper32 & 0xff;
|
||||
@@ -4240,37 +4281,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
|
||||
goto clean4;
|
||||
}
|
||||
}
|
||||
hba[i]->cmd_sg_list = kmalloc(sizeof(struct Cmd_sg_list *) *
|
||||
hba[i]->nr_cmds,
|
||||
GFP_KERNEL);
|
||||
if (!hba[i]->cmd_sg_list) {
|
||||
printk(KERN_ERR "cciss%d: Cannot get memory for "
|
||||
"s/g chaining.\n", i);
|
||||
hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i],
|
||||
hba[i]->chainsize, hba[i]->nr_cmds);
|
||||
if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0)
|
||||
goto clean4;
|
||||
}
|
||||
/* Build up chain blocks for each command */
|
||||
if (hba[i]->chainsize > 0) {
|
||||
for (j = 0; j < hba[i]->nr_cmds; j++) {
|
||||
hba[i]->cmd_sg_list[j] =
|
||||
kmalloc(sizeof(struct Cmd_sg_list),
|
||||
GFP_KERNEL);
|
||||
if (!hba[i]->cmd_sg_list[j]) {
|
||||
printk(KERN_ERR "cciss%d: Cannot get memory "
|
||||
"for chain block.\n", i);
|
||||
goto clean4;
|
||||
}
|
||||
/* Need a block of chainsized s/g elements. */
|
||||
hba[i]->cmd_sg_list[j]->sgchain =
|
||||
kmalloc((hba[i]->chainsize *
|
||||
sizeof(SGDescriptor_struct)),
|
||||
GFP_KERNEL);
|
||||
if (!hba[i]->cmd_sg_list[j]->sgchain) {
|
||||
printk(KERN_ERR "cciss%d: Cannot get memory "
|
||||
"for s/g chains\n", i);
|
||||
goto clean4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_init(&hba[i]->lock);
|
||||
|
||||
@@ -4329,16 +4343,7 @@ clean4:
|
||||
for (k = 0; k < hba[i]->nr_cmds; k++)
|
||||
kfree(hba[i]->scatter_list[k]);
|
||||
kfree(hba[i]->scatter_list);
|
||||
/* Only free up extra s/g lists if controller supports them */
|
||||
if (hba[i]->chainsize > 0) {
|
||||
for (j = 0; j < hba[i]->nr_cmds; j++) {
|
||||
if (hba[i]->cmd_sg_list[j]) {
|
||||
kfree(hba[i]->cmd_sg_list[j]->sgchain);
|
||||
kfree(hba[i]->cmd_sg_list[j]);
|
||||
}
|
||||
}
|
||||
kfree(hba[i]->cmd_sg_list);
|
||||
}
|
||||
cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
|
||||
if (hba[i]->cmd_pool)
|
||||
pci_free_consistent(hba[i]->pdev,
|
||||
hba[i]->nr_cmds * sizeof(CommandList_struct),
|
||||
@@ -4456,16 +4461,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
|
||||
for (j = 0; j < hba[i]->nr_cmds; j++)
|
||||
kfree(hba[i]->scatter_list[j]);
|
||||
kfree(hba[i]->scatter_list);
|
||||
/* Only free up extra s/g lists if controller supports them */
|
||||
if (hba[i]->chainsize > 0) {
|
||||
for (j = 0; j < hba[i]->nr_cmds; j++) {
|
||||
if (hba[i]->cmd_sg_list[j]) {
|
||||
kfree(hba[i]->cmd_sg_list[j]->sgchain);
|
||||
kfree(hba[i]->cmd_sg_list[j]);
|
||||
}
|
||||
}
|
||||
kfree(hba[i]->cmd_sg_list);
|
||||
}
|
||||
cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds);
|
||||
/*
|
||||
* Deliberately omit pci_disable_device(): it does something nasty to
|
||||
* Smart Array controllers that pci_enable_device does not undo
|
||||
@@ -4498,7 +4494,7 @@ static int __init cciss_init(void)
|
||||
* boundary. Given that we use pci_alloc_consistent() to allocate an
|
||||
* array of them, the size must be a multiple of 8 bytes.
|
||||
*/
|
||||
BUILD_BUG_ON(sizeof(CommandList_struct) % 8);
|
||||
BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT);
|
||||
|
||||
printk(KERN_INFO DRIVER_NAME "\n");
|
||||
|
||||
|
||||
+6
-15
@@ -55,18 +55,12 @@ typedef struct _drive_info_struct
|
||||
char device_initialized; /* indicates whether dev is initialized */
|
||||
} drive_info_struct;
|
||||
|
||||
struct Cmd_sg_list {
|
||||
SGDescriptor_struct *sgchain;
|
||||
dma_addr_t sg_chain_dma;
|
||||
int chain_block_size;
|
||||
};
|
||||
|
||||
struct ctlr_info
|
||||
{
|
||||
int ctlr;
|
||||
char devname[8];
|
||||
char *product_name;
|
||||
char firm_ver[4]; // Firmware version
|
||||
char firm_ver[4]; /* Firmware version */
|
||||
struct pci_dev *pdev;
|
||||
__u32 board_id;
|
||||
void __iomem *vaddr;
|
||||
@@ -89,7 +83,7 @@ struct ctlr_info
|
||||
int maxsgentries;
|
||||
int chainsize;
|
||||
int max_cmd_sgentries;
|
||||
struct Cmd_sg_list **cmd_sg_list;
|
||||
SGDescriptor_struct **cmd_sg_list;
|
||||
|
||||
# define DOORBELL_INT 0
|
||||
# define PERF_MODE_INT 1
|
||||
@@ -103,7 +97,7 @@ struct ctlr_info
|
||||
BYTE cciss_write;
|
||||
BYTE cciss_read_capacity;
|
||||
|
||||
// information about each logical volume
|
||||
/* information about each logical volume */
|
||||
drive_info_struct *drv[CISS_MAX_LUN];
|
||||
|
||||
struct access_method access;
|
||||
@@ -116,7 +110,7 @@ struct ctlr_info
|
||||
unsigned int maxSG;
|
||||
spinlock_t lock;
|
||||
|
||||
//* pointers to command and error info pool */
|
||||
/* pointers to command and error info pool */
|
||||
CommandList_struct *cmd_pool;
|
||||
dma_addr_t cmd_pool_dhandle;
|
||||
ErrorInfo_struct *errinfo_pool;
|
||||
@@ -134,12 +128,10 @@ struct ctlr_info
|
||||
*/
|
||||
int next_to_run;
|
||||
|
||||
// Disk structures we need to pass back
|
||||
/* Disk structures we need to pass back */
|
||||
struct gendisk *gendisk[CISS_MAX_LUN];
|
||||
#ifdef CONFIG_CISS_SCSI_TAPE
|
||||
void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
|
||||
/* list of block side commands the scsi error handling sucked up */
|
||||
/* and saved for later processing */
|
||||
struct cciss_scsi_adapter_data_t *scsi_ctlr;
|
||||
#endif
|
||||
unsigned char alive;
|
||||
struct list_head scan_list;
|
||||
@@ -315,4 +307,3 @@ struct board_type {
|
||||
#define CCISS_LOCK(i) (&hba[i]->lock)
|
||||
|
||||
#endif /* CCISS_H */
|
||||
|
||||
|
||||
+31
-133
@@ -1,31 +1,16 @@
|
||||
#ifndef CCISS_CMD_H
|
||||
#define CCISS_CMD_H
|
||||
//###########################################################################
|
||||
//DEFINES
|
||||
//###########################################################################
|
||||
|
||||
#include <linux/cciss_defs.h>
|
||||
|
||||
/* DEFINES */
|
||||
#define CISS_VERSION "1.00"
|
||||
|
||||
//general boundary definitions
|
||||
#define SENSEINFOBYTES 32//note that this value may vary between host implementations
|
||||
/* general boundary definitions */
|
||||
#define MAXSGENTRIES 32
|
||||
#define CCISS_SG_CHAIN 0x80000000
|
||||
#define MAXREPLYQS 256
|
||||
|
||||
//Command Status value
|
||||
#define CMD_SUCCESS 0x0000
|
||||
#define CMD_TARGET_STATUS 0x0001
|
||||
#define CMD_DATA_UNDERRUN 0x0002
|
||||
#define CMD_DATA_OVERRUN 0x0003
|
||||
#define CMD_INVALID 0x0004
|
||||
#define CMD_PROTOCOL_ERR 0x0005
|
||||
#define CMD_HARDWARE_ERR 0x0006
|
||||
#define CMD_CONNECTION_LOST 0x0007
|
||||
#define CMD_ABORTED 0x0008
|
||||
#define CMD_ABORT_FAILED 0x0009
|
||||
#define CMD_UNSOLICITED_ABORT 0x000A
|
||||
#define CMD_TIMEOUT 0x000B
|
||||
#define CMD_UNABORTABLE 0x000C
|
||||
|
||||
/* Unit Attentions ASC's as defined for the MSA2012sa */
|
||||
#define POWER_OR_RESET 0x29
|
||||
#define STATE_CHANGED 0x2a
|
||||
@@ -49,30 +34,13 @@
|
||||
#define ASYM_ACCESS_CHANGED 0x06
|
||||
#define LUN_CAPACITY_CHANGED 0x09
|
||||
|
||||
//transfer direction
|
||||
#define XFER_NONE 0x00
|
||||
#define XFER_WRITE 0x01
|
||||
#define XFER_READ 0x02
|
||||
#define XFER_RSVD 0x03
|
||||
|
||||
//task attribute
|
||||
#define ATTR_UNTAGGED 0x00
|
||||
#define ATTR_SIMPLE 0x04
|
||||
#define ATTR_HEADOFQUEUE 0x05
|
||||
#define ATTR_ORDERED 0x06
|
||||
#define ATTR_ACA 0x07
|
||||
|
||||
//cdb type
|
||||
#define TYPE_CMD 0x00
|
||||
#define TYPE_MSG 0x01
|
||||
|
||||
//config space register offsets
|
||||
/* config space register offsets */
|
||||
#define CFG_VENDORID 0x00
|
||||
#define CFG_DEVICEID 0x02
|
||||
#define CFG_I2OBAR 0x10
|
||||
#define CFG_MEM1BAR 0x14
|
||||
|
||||
//i2o space register offsets
|
||||
/* i2o space register offsets */
|
||||
#define I2O_IBDB_SET 0x20
|
||||
#define I2O_IBDB_CLEAR 0x70
|
||||
#define I2O_INT_STATUS 0x30
|
||||
@@ -81,7 +49,7 @@
|
||||
#define I2O_OBPOST_Q 0x44
|
||||
#define I2O_DMA1_CFG 0x214
|
||||
|
||||
//Configuration Table
|
||||
/* Configuration Table */
|
||||
#define CFGTBL_ChangeReq 0x00000001l
|
||||
#define CFGTBL_AccCmds 0x00000001l
|
||||
|
||||
@@ -103,24 +71,17 @@ typedef union _u64bit
|
||||
__u64 val;
|
||||
} u64bit;
|
||||
|
||||
// Type defs used in the following structs
|
||||
#define BYTE __u8
|
||||
#define WORD __u16
|
||||
#define HWORD __u16
|
||||
#define DWORD __u32
|
||||
/* Type defs used in the following structs */
|
||||
#define QWORD vals32
|
||||
|
||||
//###########################################################################
|
||||
//STRUCTURES
|
||||
//###########################################################################
|
||||
#define CISS_MAX_LUN 1024
|
||||
/* STRUCTURES */
|
||||
#define CISS_MAX_PHYS_LUN 1024
|
||||
// SCSI-3 Cmmands
|
||||
/* SCSI-3 Cmmands */
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define CISS_INQUIRY 0x12
|
||||
//Date returned
|
||||
/* Date returned */
|
||||
typedef struct _InquiryData_struct
|
||||
{
|
||||
BYTE data_byte[36];
|
||||
@@ -128,7 +89,7 @@ typedef struct _InquiryData_struct
|
||||
|
||||
#define CISS_REPORT_LOG 0xc2 /* Report Logical LUNs */
|
||||
#define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */
|
||||
// Data returned
|
||||
/* Data returned */
|
||||
typedef struct _ReportLUNdata_struct
|
||||
{
|
||||
BYTE LUNListLength[4];
|
||||
@@ -139,8 +100,8 @@ typedef struct _ReportLUNdata_struct
|
||||
#define CCISS_READ_CAPACITY 0x25 /* Read Capacity */
|
||||
typedef struct _ReadCapdata_struct
|
||||
{
|
||||
BYTE total_size[4]; // Total size in blocks
|
||||
BYTE block_size[4]; // Size of blocks in bytes
|
||||
BYTE total_size[4]; /* Total size in blocks */
|
||||
BYTE block_size[4]; /* Size of blocks in bytes */
|
||||
} ReadCapdata_struct;
|
||||
|
||||
#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */
|
||||
@@ -172,52 +133,13 @@ typedef struct _ReadCapdata_struct_16
|
||||
#define CDB_LEN10 10
|
||||
#define CDB_LEN16 16
|
||||
|
||||
// BMIC commands
|
||||
/* BMIC commands */
|
||||
#define BMIC_READ 0x26
|
||||
#define BMIC_WRITE 0x27
|
||||
#define BMIC_CACHE_FLUSH 0xc2
|
||||
#define CCISS_CACHE_FLUSH 0x01 //C2 was already being used by CCISS
|
||||
|
||||
//Command List Structure
|
||||
typedef union _SCSI3Addr_struct {
|
||||
struct {
|
||||
BYTE Dev;
|
||||
BYTE Bus:6;
|
||||
BYTE Mode:2; // b00
|
||||
} PeripDev;
|
||||
struct {
|
||||
BYTE DevLSB;
|
||||
BYTE DevMSB:6;
|
||||
BYTE Mode:2; // b01
|
||||
} LogDev;
|
||||
struct {
|
||||
BYTE Dev:5;
|
||||
BYTE Bus:3;
|
||||
BYTE Targ:6;
|
||||
BYTE Mode:2; // b10
|
||||
} LogUnit;
|
||||
} SCSI3Addr_struct;
|
||||
|
||||
typedef struct _PhysDevAddr_struct {
|
||||
DWORD TargetId:24;
|
||||
DWORD Bus:6;
|
||||
DWORD Mode:2;
|
||||
SCSI3Addr_struct Target[2]; //2 level target device addr
|
||||
} PhysDevAddr_struct;
|
||||
|
||||
typedef struct _LogDevAddr_struct {
|
||||
DWORD VolId:30;
|
||||
DWORD Mode:2;
|
||||
BYTE reserved[4];
|
||||
} LogDevAddr_struct;
|
||||
|
||||
typedef union _LUNAddr_struct {
|
||||
BYTE LunAddrBytes[8];
|
||||
SCSI3Addr_struct SCSI3Lun[4];
|
||||
PhysDevAddr_struct PhysDev;
|
||||
LogDevAddr_struct LogDev;
|
||||
} LUNAddr_struct;
|
||||
#define CCISS_CACHE_FLUSH 0x01 /* C2 was already being used by CCISS */
|
||||
|
||||
/* Command List Structure */
|
||||
#define CTLR_LUNID "\0\0\0\0\0\0\0\0"
|
||||
|
||||
typedef struct _CommandListHeader_struct {
|
||||
@@ -227,16 +149,6 @@ typedef struct _CommandListHeader_struct {
|
||||
QWORD Tag;
|
||||
LUNAddr_struct LUN;
|
||||
} CommandListHeader_struct;
|
||||
typedef struct _RequestBlock_struct {
|
||||
BYTE CDBLen;
|
||||
struct {
|
||||
BYTE Type:3;
|
||||
BYTE Attribute:3;
|
||||
BYTE Direction:2;
|
||||
} Type;
|
||||
HWORD Timeout;
|
||||
BYTE CDB[16];
|
||||
} RequestBlock_struct;
|
||||
typedef struct _ErrDescriptor_struct {
|
||||
QWORD Addr;
|
||||
DWORD Len;
|
||||
@@ -247,28 +159,6 @@ typedef struct _SGDescriptor_struct {
|
||||
DWORD Ext;
|
||||
} SGDescriptor_struct;
|
||||
|
||||
typedef union _MoreErrInfo_struct{
|
||||
struct {
|
||||
BYTE Reserved[3];
|
||||
BYTE Type;
|
||||
DWORD ErrorInfo;
|
||||
}Common_Info;
|
||||
struct{
|
||||
BYTE Reserved[2];
|
||||
BYTE offense_size;//size of offending entry
|
||||
BYTE offense_num; //byte # of offense 0-base
|
||||
DWORD offense_value;
|
||||
}Invalid_Cmd;
|
||||
}MoreErrInfo_struct;
|
||||
typedef struct _ErrorInfo_struct {
|
||||
BYTE ScsiStatus;
|
||||
BYTE SenseLen;
|
||||
HWORD CommandStatus;
|
||||
DWORD ResidualCnt;
|
||||
MoreErrInfo_struct MoreErrInfo;
|
||||
BYTE SenseInfo[SENSEINFOBYTES];
|
||||
} ErrorInfo_struct;
|
||||
|
||||
/* Command types */
|
||||
#define CMD_RWREQ 0x00
|
||||
#define CMD_IOCTL_PEND 0x01
|
||||
@@ -277,10 +167,18 @@ typedef struct _ErrorInfo_struct {
|
||||
#define CMD_MSG_TIMEOUT 0x05
|
||||
#define CMD_MSG_STALE 0xff
|
||||
|
||||
/* This structure needs to be divisible by 8 for new
|
||||
* indexing method.
|
||||
/* This structure needs to be divisible by COMMANDLIST_ALIGNMENT
|
||||
* because low bits of the address are used to to indicate that
|
||||
* whether the tag contains an index or an address. PAD_32 and
|
||||
* PAD_64 can be adjusted independently as needed for 32-bit
|
||||
* and 64-bits systems.
|
||||
*/
|
||||
#define PADSIZE (sizeof(long) - 4)
|
||||
#define COMMANDLIST_ALIGNMENT (8)
|
||||
#define IS_64_BIT ((sizeof(long) - 4)/4)
|
||||
#define IS_32_BIT (!IS_64_BIT)
|
||||
#define PAD_32 (0)
|
||||
#define PAD_64 (4)
|
||||
#define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64)
|
||||
typedef struct _CommandList_struct {
|
||||
CommandListHeader_struct Header;
|
||||
RequestBlock_struct Request;
|
||||
@@ -300,7 +198,7 @@ typedef struct _CommandList_struct {
|
||||
char pad[PADSIZE];
|
||||
} CommandList_struct;
|
||||
|
||||
//Configuration Table Structure
|
||||
/* Configuration Table Structure */
|
||||
typedef struct _HostWrite_struct {
|
||||
DWORD TransportRequest;
|
||||
DWORD Reserved;
|
||||
@@ -326,4 +224,4 @@ typedef struct _CfgTable_struct {
|
||||
DWORD MaxPhysicalDrivesPerLogicalUnit;
|
||||
} CfgTable_struct;
|
||||
#pragma pack()
|
||||
#endif // CCISS_CMD_H
|
||||
#endif /* CCISS_CMD_H */
|
||||
|
||||
+87
-54
@@ -84,7 +84,6 @@ static struct scsi_host_template cciss_driver_template = {
|
||||
.queuecommand = cciss_scsi_queue_command,
|
||||
.can_queue = SCSI_CCISS_CAN_QUEUE,
|
||||
.this_id = 7,
|
||||
.sg_tablesize = MAXSGENTRIES,
|
||||
.cmd_per_lun = 1,
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
/* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
|
||||
@@ -93,11 +92,16 @@ static struct scsi_host_template cciss_driver_template = {
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define SCSI_PAD_32 0
|
||||
#define SCSI_PAD_64 0
|
||||
|
||||
struct cciss_scsi_cmd_stack_elem_t {
|
||||
CommandList_struct cmd;
|
||||
ErrorInfo_struct Err;
|
||||
__u32 busaddr;
|
||||
__u32 pad;
|
||||
int cmdindex;
|
||||
u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
@@ -118,16 +122,15 @@ struct cciss_scsi_cmd_stack_t {
|
||||
struct cciss_scsi_adapter_data_t {
|
||||
struct Scsi_Host *scsi_host;
|
||||
struct cciss_scsi_cmd_stack_t cmd_stack;
|
||||
SGDescriptor_struct **cmd_sg_list;
|
||||
int registered;
|
||||
spinlock_t lock; // to protect ccissscsi[ctlr];
|
||||
};
|
||||
|
||||
#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
|
||||
&(((struct cciss_scsi_adapter_data_t *) \
|
||||
hba[ctlr]->scsi_ctlr)->lock), flags);
|
||||
&hba[ctlr]->scsi_ctlr->lock, flags);
|
||||
#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
|
||||
&(((struct cciss_scsi_adapter_data_t *) \
|
||||
hba[ctlr]->scsi_ctlr)->lock), flags);
|
||||
&hba[ctlr]->scsi_ctlr->lock, flags);
|
||||
|
||||
static CommandList_struct *
|
||||
scsi_cmd_alloc(ctlr_info_t *h)
|
||||
@@ -143,7 +146,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
|
||||
struct cciss_scsi_cmd_stack_t *stk;
|
||||
u64bit temp64;
|
||||
|
||||
sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
|
||||
sa = h->scsi_ctlr;
|
||||
stk = &sa->cmd_stack;
|
||||
|
||||
if (stk->top < 0)
|
||||
@@ -154,6 +157,7 @@ scsi_cmd_alloc(ctlr_info_t *h)
|
||||
memset(&c->Err, 0, sizeof(c->Err));
|
||||
/* set physical addr of cmd and addr of scsi parameters */
|
||||
c->cmd.busaddr = c->busaddr;
|
||||
c->cmd.cmdindex = c->cmdindex;
|
||||
/* (__u32) (stk->cmd_pool_handle +
|
||||
(sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
|
||||
|
||||
@@ -182,7 +186,7 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
|
||||
struct cciss_scsi_adapter_data_t *sa;
|
||||
struct cciss_scsi_cmd_stack_t *stk;
|
||||
|
||||
sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
|
||||
sa = h->scsi_ctlr;
|
||||
stk = &sa->cmd_stack;
|
||||
if (stk->top >= CMD_STACK_SIZE) {
|
||||
printk("cciss: scsi_cmd_free called too many times.\n");
|
||||
@@ -199,24 +203,31 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
|
||||
struct cciss_scsi_cmd_stack_t *stk;
|
||||
size_t size;
|
||||
|
||||
sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr],
|
||||
hba[ctlr]->chainsize, CMD_STACK_SIZE);
|
||||
if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0)
|
||||
return -ENOMEM;
|
||||
|
||||
stk = &sa->cmd_stack;
|
||||
size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
|
||||
|
||||
// pci_alloc_consistent guarantees 32-bit DMA address will
|
||||
// be used
|
||||
|
||||
/* Check alignment, see cciss_cmd.h near CommandList_struct def. */
|
||||
BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
|
||||
/* pci_alloc_consistent guarantees 32-bit DMA address will be used */
|
||||
stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
|
||||
pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
|
||||
|
||||
if (stk->pool == NULL) {
|
||||
printk("stk->pool is null\n");
|
||||
return -1;
|
||||
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
|
||||
sa->cmd_sg_list = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i=0; i<CMD_STACK_SIZE; i++) {
|
||||
stk->elem[i] = &stk->pool[i];
|
||||
stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
|
||||
(sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
|
||||
stk->elem[i]->cmdindex = i;
|
||||
}
|
||||
stk->top = CMD_STACK_SIZE-1;
|
||||
return 0;
|
||||
@@ -229,7 +240,7 @@ scsi_cmd_stack_free(int ctlr)
|
||||
struct cciss_scsi_cmd_stack_t *stk;
|
||||
size_t size;
|
||||
|
||||
sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
|
||||
sa = hba[ctlr]->scsi_ctlr;
|
||||
stk = &sa->cmd_stack;
|
||||
if (stk->top != CMD_STACK_SIZE-1) {
|
||||
printk( "cciss: %d scsi commands are still outstanding.\n",
|
||||
@@ -241,6 +252,7 @@ scsi_cmd_stack_free(int ctlr)
|
||||
|
||||
pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
|
||||
stk->pool = NULL;
|
||||
cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -530,8 +542,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno,
|
||||
CPQ_TAPE_LOCK(ctlr, flags);
|
||||
|
||||
if (hostno != -1) /* if it's not the first time... */
|
||||
sh = ((struct cciss_scsi_adapter_data_t *)
|
||||
hba[ctlr]->scsi_ctlr)->scsi_host;
|
||||
sh = hba[ctlr]->scsi_ctlr->scsi_host;
|
||||
|
||||
/* find any devices in ccissscsi[] that are not in
|
||||
sd[] and remove them from ccissscsi[] */
|
||||
@@ -702,7 +713,7 @@ cciss_scsi_setup(int cntl_num)
|
||||
kfree(shba);
|
||||
shba = NULL;
|
||||
}
|
||||
hba[cntl_num]->scsi_ctlr = (void *) shba;
|
||||
hba[cntl_num]->scsi_ctlr = shba;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -725,6 +736,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
|
||||
ctlr = hba[cp->ctlr];
|
||||
|
||||
scsi_dma_unmap(cmd);
|
||||
if (cp->Header.SGTotal > ctlr->max_cmd_sgentries)
|
||||
cciss_unmap_sg_chain_block(ctlr, cp);
|
||||
|
||||
cmd->result = (DID_OK << 16); /* host byte */
|
||||
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
|
||||
@@ -847,9 +860,10 @@ cciss_scsi_detect(int ctlr)
|
||||
sh->io_port = 0; // good enough? FIXME,
|
||||
sh->n_io_port = 0; // I don't think we use these two...
|
||||
sh->this_id = SELF_SCSI_ID;
|
||||
sh->sg_tablesize = hba[ctlr]->maxsgentries;
|
||||
|
||||
((struct cciss_scsi_adapter_data_t *)
|
||||
hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
|
||||
hba[ctlr]->scsi_ctlr)->scsi_host = sh;
|
||||
sh->hostdata[0] = (unsigned long) hba[ctlr];
|
||||
sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
|
||||
sh->unique_id = sh->irq;
|
||||
@@ -1364,34 +1378,54 @@ cciss_scsi_proc_info(struct Scsi_Host *sh,
|
||||
dma mapping and fills in the scatter gather entries of the
|
||||
cciss command, cp. */
|
||||
|
||||
static void
|
||||
cciss_scatter_gather(struct pci_dev *pdev,
|
||||
CommandList_struct *cp,
|
||||
struct scsi_cmnd *cmd)
|
||||
static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp,
|
||||
struct scsi_cmnd *cmd)
|
||||
{
|
||||
unsigned int len;
|
||||
struct scatterlist *sg;
|
||||
__u64 addr64;
|
||||
int use_sg, i;
|
||||
int request_nsgs, i, chained, sg_index;
|
||||
struct cciss_scsi_adapter_data_t *sa = h->scsi_ctlr;
|
||||
SGDescriptor_struct *curr_sg;
|
||||
|
||||
BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
|
||||
BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
|
||||
|
||||
use_sg = scsi_dma_map(cmd);
|
||||
if (use_sg) { /* not too many addrs? */
|
||||
scsi_for_each_sg(cmd, sg, use_sg, i) {
|
||||
chained = 0;
|
||||
sg_index = 0;
|
||||
curr_sg = cp->SG;
|
||||
request_nsgs = scsi_dma_map(cmd);
|
||||
if (request_nsgs) {
|
||||
scsi_for_each_sg(cmd, sg, request_nsgs, i) {
|
||||
if (sg_index + 1 == h->max_cmd_sgentries &&
|
||||
!chained && request_nsgs - i > 1) {
|
||||
chained = 1;
|
||||
sg_index = 0;
|
||||
curr_sg = sa->cmd_sg_list[cp->cmdindex];
|
||||
}
|
||||
addr64 = (__u64) sg_dma_address(sg);
|
||||
len = sg_dma_len(sg);
|
||||
cp->SG[i].Addr.lower =
|
||||
(__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
|
||||
cp->SG[i].Addr.upper =
|
||||
(__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
|
||||
cp->SG[i].Len = len;
|
||||
cp->SG[i].Ext = 0; // we are not chaining
|
||||
curr_sg[sg_index].Addr.lower =
|
||||
(__u32) (addr64 & 0x0FFFFFFFFULL);
|
||||
curr_sg[sg_index].Addr.upper =
|
||||
(__u32) ((addr64 >> 32) & 0x0FFFFFFFFULL);
|
||||
curr_sg[sg_index].Len = len;
|
||||
curr_sg[sg_index].Ext = 0;
|
||||
++sg_index;
|
||||
}
|
||||
if (chained)
|
||||
cciss_map_sg_chain_block(h, cp,
|
||||
sa->cmd_sg_list[cp->cmdindex],
|
||||
(request_nsgs - (h->max_cmd_sgentries - 1)) *
|
||||
sizeof(SGDescriptor_struct));
|
||||
}
|
||||
|
||||
cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */
|
||||
cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
|
||||
/* track how many SG entries we are using */
|
||||
if (request_nsgs > h->maxSG)
|
||||
h->maxSG = request_nsgs;
|
||||
cp->Header.SGTotal = (__u8) request_nsgs + chained;
|
||||
if (request_nsgs > h->max_cmd_sgentries)
|
||||
cp->Header.SGList = h->max_cmd_sgentries;
|
||||
else
|
||||
cp->Header.SGList = cp->Header.SGTotal;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1399,7 +1433,7 @@ cciss_scatter_gather(struct pci_dev *pdev,
|
||||
static int
|
||||
cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
|
||||
{
|
||||
ctlr_info_t **c;
|
||||
ctlr_info_t *c;
|
||||
int ctlr, rc;
|
||||
unsigned char scsi3addr[8];
|
||||
CommandList_struct *cp;
|
||||
@@ -1407,8 +1441,8 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
|
||||
|
||||
// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
|
||||
// We violate cmd->host privacy here. (Is there another way?)
|
||||
c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
|
||||
ctlr = (*c)->ctlr;
|
||||
c = (ctlr_info_t *) cmd->device->host->hostdata[0];
|
||||
ctlr = c->ctlr;
|
||||
|
||||
rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
|
||||
cmd->device->lun, scsi3addr);
|
||||
@@ -1431,7 +1465,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
|
||||
see what the device thinks of it. */
|
||||
|
||||
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
|
||||
cp = scsi_cmd_alloc(*c);
|
||||
cp = scsi_cmd_alloc(c);
|
||||
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
|
||||
if (cp == NULL) { /* trouble... */
|
||||
printk("scsi_cmd_alloc returned NULL!\n");
|
||||
@@ -1489,15 +1523,14 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
|
||||
cciss_scatter_gather(c, cp, cmd);
|
||||
|
||||
/* Put the request on the tail of the request queue */
|
||||
|
||||
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
|
||||
addQ(&(*c)->reqQ, cp);
|
||||
(*c)->Qdepth++;
|
||||
start_io(*c);
|
||||
addQ(&c->reqQ, cp);
|
||||
c->Qdepth++;
|
||||
start_io(c);
|
||||
spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
|
||||
|
||||
/* the cmd'll come back via intr handler in complete_scsi_command() */
|
||||
@@ -1514,7 +1547,7 @@ cciss_unregister_scsi(int ctlr)
|
||||
/* we are being forcibly unloaded, and may not refuse. */
|
||||
|
||||
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
|
||||
sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
|
||||
sa = hba[ctlr]->scsi_ctlr;
|
||||
stk = &sa->cmd_stack;
|
||||
|
||||
/* if we weren't ever actually registered, don't unregister */
|
||||
@@ -1541,7 +1574,7 @@ cciss_engage_scsi(int ctlr)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
|
||||
sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
|
||||
sa = hba[ctlr]->scsi_ctlr;
|
||||
stk = &sa->cmd_stack;
|
||||
|
||||
if (sa->registered) {
|
||||
@@ -1654,14 +1687,14 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
|
||||
int rc;
|
||||
CommandList_struct *cmd_in_trouble;
|
||||
unsigned char lunaddr[8];
|
||||
ctlr_info_t **c;
|
||||
ctlr_info_t *c;
|
||||
int ctlr;
|
||||
|
||||
/* find the controller to which the command to be aborted was sent */
|
||||
c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
|
||||
c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
|
||||
if (c == NULL) /* paranoia */
|
||||
return FAILED;
|
||||
ctlr = (*c)->ctlr;
|
||||
ctlr = c->ctlr;
|
||||
printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
|
||||
/* find the command that's giving us trouble */
|
||||
cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
|
||||
@@ -1671,7 +1704,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
|
||||
/* send a reset to the SCSI LUN which the command was sent to */
|
||||
rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr,
|
||||
TYPE_MSG);
|
||||
if (rc == 0 && wait_for_device_to_become_ready(*c, lunaddr) == 0)
|
||||
if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0)
|
||||
return SUCCESS;
|
||||
printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
|
||||
return FAILED;
|
||||
@@ -1682,14 +1715,14 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
|
||||
int rc;
|
||||
CommandList_struct *cmd_to_abort;
|
||||
unsigned char lunaddr[8];
|
||||
ctlr_info_t **c;
|
||||
ctlr_info_t *c;
|
||||
int ctlr;
|
||||
|
||||
/* find the controller to which the command to be aborted was sent */
|
||||
c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
|
||||
c = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
|
||||
if (c == NULL) /* paranoia */
|
||||
return FAILED;
|
||||
ctlr = (*c)->ctlr;
|
||||
ctlr = c->ctlr;
|
||||
printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
|
||||
|
||||
/* find the command to be aborted */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user