提交 0481990b 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6

====================================================================
= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28 =
= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v7.0 =
= README for =
= The Linux Operating System =
====================================================================
......@@ -131,6 +131,10 @@ The following information is available in this file:
SCSI "stub" effects.
2. Version History
7.0 (4th August, 2005)
- Updated driver to use SCSI transport class infrastructure
- Upported sequencer and core fixes from last adaptec released
version of the driver.
6.2.36 (June 3rd, 2003)
- Correct code that disables PCI parity error checking.
- Correct and simplify handling of the ignore wide residue
......
......@@ -373,13 +373,11 @@ Summary:
scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance
scsi_add_host - perform sysfs registration and SCSI bus scan.
scsi_add_timer - (re-)start timer on a SCSI command.
scsi_adjust_queue_depth - change the queue depth on a SCSI device
scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table
scsi_block_requests - prevent further commands being queued to given host
scsi_deactivate_tcq - turn off tag command queueing
scsi_delete_timer - cancel timer on a SCSI command.
scsi_host_alloc - return a new scsi_host instance whose refcount==1
scsi_host_get - increments Scsi_Host instance's refcount
scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
......@@ -457,27 +455,6 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
/**
* scsi_add_timer - (re-)start timer on a SCSI command.
* @scmd: pointer to scsi command instance
* @timeout: duration of timeout in "jiffies"
* @complete: pointer to function to call if timeout expires
*
* Returns nothing
*
* Might block: no
*
* Notes: Each scsi command has its own timer, and as it is added
* to the queue, we set up the timer. When the command completes,
* we cancel the timer. An LLD can use this function to change
* the existing timeout value.
*
* Defined in: drivers/scsi/scsi_error.c
**/
void scsi_add_timer(struct scsi_cmnd *scmd, int timeout,
void (*complete)(struct scsi_cmnd *))
/**
* scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device
* @sdev: pointer to SCSI device to change queue depth on
......@@ -565,24 +542,6 @@ void scsi_block_requests(struct Scsi_Host * shost)
void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
/**
* scsi_delete_timer - cancel timer on a SCSI command.
* @scmd: pointer to scsi command instance
*
* Returns 1 if able to cancel timer else 0 (i.e. too late or already
* cancelled).
*
* Might block: no [may in the future if it invokes del_timer_sync()]
*
* Notes: All commands issued by upper levels already have a timeout
* associated with them. An LLD can use this function to cancel the
* timer.
*
* Defined in: drivers/scsi/scsi_error.c
**/
int scsi_delete_timer(struct scsi_cmnd *scmd)
/**
* scsi_host_alloc - create a scsi host adapter instance and perform basic
* initialization.
......
......@@ -822,6 +822,13 @@ L: emu10k1-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/emu10k1/
S: Maintained
EMULEX LPFC FC SCSI DRIVER
P: James Smart
M: james.smart@emulex.com
L: linux-scsi@vger.kernel.org
W: http://sourceforge.net/projects/lpfcxxxx
S: Supported
EPSON 1355 FRAMEBUFFER DRIVER
P: Christopher Hoover
M: ch@murgatroid.com, ch@hpl.hp.com
......
......@@ -22,11 +22,26 @@
/* This is a private structure used to tie the classdev and the
* container .. it should never be visible outside this file */
struct internal_container {
struct list_head node;
struct klist_node node;
struct attribute_container *cont;
struct class_device classdev;
};
static void internal_container_klist_get(struct klist_node *n)
{
struct internal_container *ic =
container_of(n, struct internal_container, node);
class_device_get(&ic->classdev);
}
static void internal_container_klist_put(struct klist_node *n)
{
struct internal_container *ic =
container_of(n, struct internal_container, node);
class_device_put(&ic->classdev);
}
/**
* attribute_container_classdev_to_container - given a classdev, return the container
*
......@@ -57,7 +72,8 @@ int
attribute_container_register(struct attribute_container *cont)
{
INIT_LIST_HEAD(&cont->node);
INIT_LIST_HEAD(&cont->containers);
klist_init(&cont->containers,internal_container_klist_get,
internal_container_klist_put);
down(&attribute_container_mutex);
list_add_tail(&cont->node, &attribute_container_list);
......@@ -77,11 +93,13 @@ attribute_container_unregister(struct attribute_container *cont)
{
int retval = -EBUSY;
down(&attribute_container_mutex);
if (!list_empty(&cont->containers))
spin_lock(&cont->containers.k_lock);
if (!list_empty(&cont->containers.k_list))
goto out;
retval = 0;
list_del(&cont->node);
out:
spin_unlock(&cont->containers.k_lock);
up(&attribute_container_mutex);
return retval;
......@@ -140,7 +158,6 @@ attribute_container_add_device(struct device *dev,
continue;
}
memset(ic, 0, sizeof(struct internal_container));
INIT_LIST_HEAD(&ic->node);
ic->cont = cont;
class_device_initialize(&ic->classdev);
ic->classdev.dev = get_device(dev);
......@@ -151,11 +168,22 @@ attribute_container_add_device(struct device *dev,
fn(cont, dev, &ic->classdev);
else
attribute_container_add_class_device(&ic->classdev);
list_add_tail(&ic->node, &cont->containers);
klist_add_tail(&ic->node, &cont->containers);
}
up(&attribute_container_mutex);
}
/* FIXME: can't break out of this unless klist_iter_exit is also
* called before doing the break
*/
#define klist_for_each_entry(pos, head, member, iter) \
for (klist_iter_init(head, iter); (pos = ({ \
struct klist_node *n = klist_next(iter); \
n ? container_of(n, typeof(*pos), member) : \
({ klist_iter_exit(iter) ; NULL; }); \
}) ) != NULL; )
/**
* attribute_container_remove_device - make device eligible for removal.
*
......@@ -182,17 +210,19 @@ attribute_container_remove_device(struct device *dev,
down(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic, *tmp;
struct internal_container *ic;
struct klist_iter iter;
if (attribute_container_no_classdevs(cont))
continue;
if (!cont->match(cont, dev))
continue;
list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
klist_for_each_entry(ic, &cont->containers, node, &iter) {
if (dev != ic->classdev.dev)
continue;
list_del(&ic->node);
klist_del(&ic->node);
if (fn)
fn(cont, dev, &ic->classdev);
else {
......@@ -225,12 +255,18 @@ attribute_container_device_trigger(struct device *dev,
down(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic, *tmp;
struct internal_container *ic;
struct klist_iter iter;
if (!cont->match(cont, dev))
continue;
list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
if (attribute_container_no_classdevs(cont)) {
fn(cont, dev, NULL);
continue;
}
klist_for_each_entry(ic, &cont->containers, node, &iter) {
if (dev == ic->classdev.dev)
fn(cont, dev, &ic->classdev);
}
......@@ -368,6 +404,36 @@ attribute_container_class_device_del(struct class_device *classdev)
}
EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
/**
* attribute_container_find_class_device - find the corresponding class_device
*
* @cont: the container
* @dev: the generic device
*
* Looks up the device in the container's list of class devices and returns
* the corresponding class_device.
*/
struct class_device *
attribute_container_find_class_device(struct attribute_container *cont,
struct device *dev)
{
struct class_device *cdev = NULL;
struct internal_container *ic;
struct klist_iter iter;
klist_for_each_entry(ic, &cont->containers, node, &iter) {
if (ic->classdev.dev == dev) {
cdev = &ic->classdev;
/* FIXME: must exit iterator then break */
klist_iter_exit(&iter);
break;
}
}
return cdev;
}
EXPORT_SYMBOL_GPL(attribute_container_find_class_device);
int __init
attribute_container_init(void)
{
......
......@@ -7,7 +7,7 @@
* This file is licensed under GPLv2
*
* The basic idea here is to allow any "device controller" (which
* would most often be a Host Bus Adapter" to use the services of one
* would most often be a Host Bus Adapter to use the services of one
* or more tranport classes for performing transport specific
* services. Transport specific services are things that the generic
* command layer doesn't want to know about (speed settings, line
......@@ -64,7 +64,9 @@ void transport_class_unregister(struct transport_class *tclass)
}
EXPORT_SYMBOL_GPL(transport_class_unregister);
static int anon_transport_dummy_function(struct device *dev)
static int anon_transport_dummy_function(struct transport_container *tc,
struct device *dev,
struct class_device *cdev)
{
/* do nothing */
return 0;
......@@ -115,9 +117,10 @@ static int transport_setup_classdev(struct attribute_container *cont,
struct class_device *classdev)
{
struct transport_class *tclass = class_to_transport_class(cont->class);
struct transport_container *tcont = attribute_container_to_transport_container(cont);
if (tclass->setup)
tclass->setup(dev);
tclass->setup(tcont, dev, classdev);
return 0;
}
......@@ -178,12 +181,14 @@ void transport_add_device(struct device *dev)
EXPORT_SYMBOL_GPL(transport_add_device);
static int transport_configure(struct attribute_container *cont,
struct device *dev)
struct device *dev,
struct class_device *cdev)
{
struct transport_class *tclass = class_to_transport_class(cont->class);
struct transport_container *tcont = attribute_container_to_transport_container(cont);
if (tclass->configure)
tclass->configure(dev);
tclass->configure(tcont, dev, cdev);
return 0;
}
......@@ -202,7 +207,7 @@ static int transport_configure(struct attribute_container *cont,
*/
void transport_configure_device(struct device *dev)
{
attribute_container_trigger(dev, transport_configure);
attribute_container_device_trigger(dev, transport_configure);
}
EXPORT_SYMBOL_GPL(transport_configure_device);
......@@ -215,7 +220,7 @@ static int transport_remove_classdev(struct attribute_container *cont,
struct transport_class *tclass = class_to_transport_class(cont->class);
if (tclass->remove)
tclass->remove(dev);
tclass->remove(tcont, dev, classdev);
if (tclass->remove != anon_transport_dummy_function) {
if (tcont->statistics)
......
......@@ -284,6 +284,7 @@ static inline void rq_init(request_queue_t *q, struct request *rq)
rq->special = NULL;
rq->data_len = 0;
rq->data = NULL;
rq->nr_phys_segments = 0;
rq->sense = NULL;
rq->end_io = NULL;
rq->end_io_data = NULL;
......@@ -2115,7 +2116,7 @@ EXPORT_SYMBOL(blk_insert_request);
/**
* blk_rq_map_user - map user data to a request, for REQ_BLOCK_PC usage
* @q: request queue where request should be inserted
* @rw: READ or WRITE data
* @rq: request structure to fill
* @ubuf: the user buffer
* @len: length of user data
*
......@@ -2132,21 +2133,19 @@ EXPORT_SYMBOL(blk_insert_request);
* original bio must be passed back in to blk_rq_unmap_user() for proper
* unmapping.
*/
struct request *blk_rq_map_user(request_queue_t *q, int rw, void __user *ubuf,
unsigned int len)
int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
unsigned int len)
{
unsigned long uaddr;
struct request *rq;
struct bio *bio;
int reading;
if (len > (q->max_sectors << 9))
return ERR_PTR(-EINVAL);
if ((!len && ubuf) || (len && !ubuf))
return ERR_PTR(-EINVAL);
return -EINVAL;
if (!len || !ubuf)
return -EINVAL;
rq = blk_get_request(q, rw, __GFP_WAIT);
if (!rq)
return ERR_PTR(-ENOMEM);
reading = rq_data_dir(rq) == READ;
/*
* if alignment requirement is satisfied, map in user pages for
......@@ -2154,9 +2153,9 @@ struct request *blk_rq_map_user(request_queue_t *q, int rw, void __user *ubuf,
*/
uaddr = (unsigned long) ubuf;
if (!(uaddr & queue_dma_alignment(q)) && !(len & queue_dma_alignment(q)))
bio = bio_map_user(q, NULL, uaddr, len, rw == READ);
bio = bio_map_user(q, NULL, uaddr, len, reading);
else
bio = bio_copy_user(q, uaddr, len, rw == READ);
bio = bio_copy_user(q, uaddr, len, reading);
if (!IS_ERR(bio)) {
rq->bio = rq->biotail = bio;
......@@ -2164,28 +2163,70 @@ struct request *blk_rq_map_user(request_queue_t *q, int rw, void __user *ubuf,
rq->buffer = rq->data = NULL;
rq->data_len = len;
return rq;
return 0;
}
/*
* bio is the err-ptr
*/
blk_put_request(rq);
return (struct request *) bio;
return PTR_ERR(bio);
}
EXPORT_SYMBOL(blk_rq_map_user);
/**
* blk_rq_map_user_iov - map user data to a request, for REQ_BLOCK_PC usage
* @q: request queue where request should be inserted
* @rq: request to map data to
* @iov: pointer to the iovec
* @iov_count: number of elements in the iovec
*
* Description:
* Data will be mapped directly for zero copy io, if possible. Otherwise
* a kernel bounce buffer is used.
*
* A matching blk_rq_unmap_user() must be issued at the end of io, while
* still in process context.
*
* Note: The mapped bio may need to be bounced through blk_queue_bounce()
* before being submitted to the device, as pages mapped may be out of
* reach. It's the callers responsibility to make sure this happens. The
* original bio must be passed back in to blk_rq_unmap_user() for proper
* unmapping.
*/
int blk_rq_map_user_iov(request_queue_t *q, struct request *rq,
struct sg_iovec *iov, int iov_count)
{
struct bio *bio;
if (!iov || iov_count <= 0)
return -EINVAL;
/* we don't allow misaligned data like bio_map_user() does. If the
* user is using sg, they're expected to know the alignment constraints
* and respect them accordingly */
bio = bio_map_user_iov(q, NULL, iov, iov_count, rq_data_dir(rq)== READ);
if (IS_ERR(bio))
return PTR_ERR(bio);
rq->bio = rq->biotail = bio;
blk_rq_bio_prep(q, rq, bio);
rq->buffer = rq->data = NULL;
rq->data_len = bio->bi_size;
return 0;
}
EXPORT_SYMBOL(blk_rq_map_user_iov);
/**
* blk_rq_unmap_user - unmap a request with user data
* @rq: request to be unmapped
* @bio: bio for the request
* @bio: bio to be unmapped
* @ulen: length of user buffer
*
* Description:
* Unmap a request previously mapped by blk_rq_map_user().
* Unmap a bio previously mapped by blk_rq_map_user().
*/
int blk_rq_unmap_user(struct request *rq, struct bio *bio, unsigned int ulen)
int blk_rq_unmap_user(struct bio *bio, unsigned int ulen)
{
int ret = 0;
......@@ -2196,31 +2237,89 @@ int blk_rq_unmap_user(struct request *rq, struct bio *bio, unsigned int ulen)
ret = bio_uncopy_user(bio);
}
blk_put_request(rq);
return ret;
return 0;
}
EXPORT_SYMBOL(blk_rq_unmap_user);
/**
* blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
* @q: request queue where request should be inserted
* @rq: request to fill
* @kbuf: the kernel buffer
* @len: length of user data
* @gfp_mask: memory allocation flags
*/
int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
unsigned int len, unsigned int gfp_mask)
{
struct bio *bio;
if (len > (q->max_sectors << 9))
return -EINVAL;
if (!len || !kbuf)
return -EINVAL;
bio = bio_map_kern(q, kbuf, len, gfp_mask);
if (IS_ERR(bio))
return PTR_ERR(bio);
if (rq_data_dir(rq) == WRITE)
bio->bi_rw |= (1 << BIO_RW);
rq->bio = rq->biotail = bio;
blk_rq_bio_prep(q, rq, bio);
rq->buffer = rq->data = NULL;
rq->data_len = len;
return 0;
}
EXPORT_SYMBOL(blk_rq_map_kern);
/**
* blk_execute_rq_nowait - insert a request into queue for execution
* @q: queue to insert the request in
* @bd_disk: matching gendisk
* @rq: request to insert
* @at_head: insert request at head or tail of queue
* @done: I/O completion handler
*
* Description:
* Insert a fully prepared request at the back of the io scheduler queue
* for execution. Don't wait for completion.
*/
void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
struct request *rq, int at_head,
void (*done)(struct request *))
{
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
rq->rq_disk = bd_disk;
rq->flags |= REQ_NOMERGE;
rq->end_io = done;
elv_add_request(q, rq, where, 1);
generic_unplug_device(q);
}
/**
* blk_execute_rq - insert a request into queue for execution
* @q: queue to insert the request in
* @bd_disk: matching gendisk
* @rq: request to insert
* @at_head: insert request at head or tail of queue
*
* Description:
* Insert a fully prepared request at the back of the io scheduler queue
* for execution.
* for execution and wait for completion.
*/
int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
struct request *rq)
struct request *rq, int at_head)
{
DECLARE_COMPLETION(wait);
char sense[SCSI_SENSE_BUFFERSIZE];
int err = 0;
rq->rq_disk = bd_disk;
/*
* we need an extra reference to the request, so we can look at
* it after io completion
......@@ -2233,11 +2332,8 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
rq->sense_len = 0;
}
rq->flags |= REQ_NOMERGE;
rq->waiting = &wait;
rq->end_io = blk_end_sync_rq;
elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
generic_unplug_device(q);
blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
wait_for_completion(&wait);
rq->waiting = NULL;
......@@ -2277,6 +2373,44 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
EXPORT_SYMBOL(blkdev_issue_flush);
/**
* blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
* @q: device queue
* @disk: gendisk
* @error_sector: error offset
*
* Description:
* Devices understanding the SCSI command set, can use this function as
* a helper for issuing a cache flush. Note: driver is required to store
* the error offset (in case of error flushing) in ->sector of struct
* request.
*/
int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
sector_t *error_sector)
{
struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
int ret;
rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
rq->sector = 0;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd[0] = 0x35;
rq->cmd_len = 12;
rq->data = NULL;
rq->data_len = 0;
rq->timeout = 60 * HZ;
ret = blk_execute_rq(q, disk, rq, 0);
if (ret && error_sector)
*error_sector = rq->sector;
blk_put_request(rq);
return ret;
}
EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
{
int rw = rq_data_dir(rq);
......
......@@ -216,7 +216,7 @@ static int sg_io(struct file *file, request_queue_t *q,
struct gendisk *bd_disk, struct sg_io_hdr *hdr)
{
unsigned long start_time;
int reading, writing;
int writing = 0, ret = 0;
struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
......@@ -231,38 +231,48 @@ static int sg_io(struct file *file, request_queue_t *q,
if (verify_command(file, cmd))
return -EPERM;
/*
* we'll do that later
*/
if (hdr->iovec_count)
return -EOPNOTSUPP;
if (hdr->dxfer_len > (q->max_sectors << 9))
return -EIO;
reading = writing = 0;
if (hdr->dxfer_len) {
if (hdr->dxfer_len)
switch (hdr->dxfer_direction) {
default:
return -EINVAL;
case SG_DXFER_TO_FROM_DEV:
reading = 1;
/* fall through */
case SG_DXFER_TO_DEV:
writing = 1;
break;
case SG_DXFER_FROM_DEV:
reading = 1;
break;
}
rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp,
hdr->dxfer_len);
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
if (!rq)
return -ENOMEM;
if (hdr->iovec_count) {
const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
struct sg_iovec *iov;
iov = kmalloc(size, GFP_KERNEL);
if (!iov) {
ret = -ENOMEM;
goto out;
}
if (copy_from_user(iov, hdr->dxferp, size)) {
kfree(iov);
ret = -EFAULT;
goto out;
}
ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
kfree(iov);
} else if (hdr->dxfer_len)
ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
if (IS_ERR(rq))
return PTR_ERR(rq);
} else
rq = blk_get_request(q, READ, __GFP_WAIT);
if (ret)
goto out;
/*
* fill in request structure
......@@ -298,7 +308,7 @@ static int sg_io(struct file *file, request_queue_t *q,
* (if he doesn't check that is his problem).
* N.B. a non-zero SCSI status is _not_ necessarily an error.
*/
blk_execute_rq(q, bd_disk, rq);
blk_execute_rq(q, bd_disk, rq, 0);
/* write to all output members */
hdr->status = 0xff & rq->errors;
......@@ -320,12 +330,14 @@ static int sg_io(struct file *file, request_queue_t *q,
hdr->sb_len_wr = len;
}
if (blk_rq_unmap_user(rq, bio, hdr->dxfer_len))
return -EFAULT;
if (blk_rq_unmap_user(bio, hdr->dxfer_len))
ret = -EFAULT;
/* may not have succeeded, but output values written to control
* structure (struct sg_io_hdr). */
return 0;
out:
blk_put_request(rq);
return ret;
}
#define OMAX_SB_LEN 16 /* For backward compatibility */
......@@ -408,7 +420,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
rq->data_len = bytes;
rq->flags |= REQ_BLOCK_PC;
blk_execute_rq(q, bd_disk, rq);
blk_execute_rq(q, bd_disk, rq, 0);
err = rq->errors & 0xff; /* only 8 bit SCSI status */
if (err) {
if (rq->sense_len && rq->sense) {
......@@ -561,7 +573,7 @@ int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd,
rq->cmd[0] = GPCMD_START_STOP_UNIT;
rq->cmd[4] = 0x02 + (close != 0);
rq->cmd_len = 6;
err = blk_execute_rq(q, bd_disk, rq);
err = blk_execute_rq(q, bd_disk, rq, 0);
blk_put_request(rq);
break;
default:
......
......@@ -2097,6 +2097,10 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
if (!q)
return -ENXIO;
rq = blk_get_request(q, READ, GFP_KERNEL);
if (!rq)
return -ENOMEM;
cdi->last_sense = 0;
while (nframes) {
......@@ -2108,9 +2112,9 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
len = nr * CD_FRAMESIZE_RAW;
rq = blk_rq_map_user(q, READ, ubuf, len);
if (IS_ERR(rq))
return PTR_ERR(rq);
ret = blk_rq_map_user(q, rq, ubuf, len);
if (ret)
break;
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd[0] = GPCMD_READ_CD;
......@@ -2132,13 +2136,13 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
if (rq->bio)
blk_queue_bounce(q, &rq->bio);
if (blk_execute_rq(q, cdi->disk, rq)) {
if (blk_execute_rq(q, cdi->disk, rq, 0)) {
struct request_sense *s = rq->sense;
ret = -EIO;
cdi->last_sense = s->sense_key;
}
if (blk_rq_unmap_user(rq, bio, len))
if (blk_rq_unmap_user(bio, len))
ret = -EFAULT;
if (ret)
......@@ -2149,6 +2153,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
ubuf += len;
}
blk_put_request(rq);
return ret;
}
......
......@@ -754,7 +754,7 @@ static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk,
idedisk_prepare_flush(q, rq);
ret = blk_execute_rq(q, disk, rq);
ret = blk_execute_rq(q, disk, rq, 0);
/*
* if we failed and caller wants error offset, get it
......
......@@ -6,7 +6,7 @@
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
* mpi.h Version: 01.05.07
* mpi.h Version: 01.05.08
*
* Version History
* ---------------
......@@ -71,6 +71,9 @@
* 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Removed EEDP IOCStatus codes.
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Added EEDP IOCStatus codes.
* --------------------------------------------------------------------------
*/
......@@ -101,7 +104,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */
#define MPI_HEADER_VERSION_UNIT (0x09)
#define MPI_HEADER_VERSION_UNIT (0x0A)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
......@@ -292,10 +295,13 @@
#define MPI_FUNCTION_DIAG_BUFFER_POST (0x1D)
#define MPI_FUNCTION_DIAG_RELEASE (0x1E)
#define MPI_FUNCTION_SCSI_IO_32 (0x1F)
#define MPI_FUNCTION_LAN_SEND (0x20)
#define MPI_FUNCTION_LAN_RECEIVE (0x21)
#define MPI_FUNCTION_LAN_RESET (0x22)
#define MPI_FUNCTION_TARGET_ASSIST_EXTENDED (0x23)
#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24)
#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25)
......@@ -680,6 +686,15 @@ typedef struct _MSG_DEFAULT_REPLY
#define MPI_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B)
#define MPI_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C)
/****************************************************************************/
/* For use by SCSI Initiator and SCSI Target end-to-end data protection */
/****************************************************************************/
#define MPI_IOCSTATUS_EEDP_GUARD_ERROR (0x004D)
#define MPI_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E)
#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F)
/****************************************************************************/
/* SCSI Target values */
/****************************************************************************/
......
......@@ -6,7 +6,7 @@
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
* mpi_cnfg.h Version: 01.05.08
* mpi_cnfg.h Version: 01.05.09
*
* Version History
* ---------------
......@@ -232,6 +232,23 @@
* New physical mapping mode in SAS IO Unit Page 2.
* Added CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added Slot and Enclosure fields to SAS Device Page 0.
* 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
* Added more RAID type defines to IOC Page 2.
* Added Port Enable Delay settings to BIOS Page 1.
* Added Bad Block Table Full define to RAID Volume Page 0.
* Added Previous State defines to RAID Physical Disk
* Page 0.
* Added Max Sata Targets define for DiscoveryStatus field
* of SAS IO Unit Page 0.
* Added Device Self Test to Control Flags of SAS IO Unit
* Page 1.
* Added Direct Attach Starting Slot Number define for SAS
* IO Unit Page 2.
* Added new fields in SAS Device Page 2 for enclosure
* mapping.
* Added OwnerDevHandle and Flags field to SAS PHY Page 0.
* Added IOC GPIO Flags define to SAS Enclosure Page 0.
* Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* --------------------------------------------------------------------------
*/
......@@ -477,6 +494,7 @@ typedef struct _MSG_CONFIG_REPLY
#define MPI_MANUFACTPAGE_DEVICEID_FC929X (0x0626)
#define MPI_MANUFACTPAGE_DEVICEID_FC939X (0x0642)
#define MPI_MANUFACTPAGE_DEVICEID_FC949X (0x0640)
#define MPI_MANUFACTPAGE_DEVICEID_FC949ES (0x0646)
/* SCSI */
#define MPI_MANUFACTPAGE_DEVID_53C1030 (0x0030)
#define MPI_MANUFACTPAGE_DEVID_53C1030ZC (0x0031)
......@@ -769,9 +787,13 @@ typedef struct _CONFIG_PAGE_IOC_1
} CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
IOCPage1_t, MPI_POINTER pIOCPage1_t;
#define MPI_IOCPAGE1_PAGEVERSION (0x02)
#define MPI_IOCPAGE1_PAGEVERSION (0x03)
/* defines for the Flags field */
#define MPI_IOCPAGE1_EEDP_MODE_MASK (0x07000000)
#define MPI_IOCPAGE1_EEDP_MODE_OFF (0x00000000)
#define MPI_IOCPAGE1_EEDP_MODE_T10 (0x01000000)
#define MPI_IOCPAGE1_EEDP_MODE_LSI_1 (0x02000000)
#define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE (0x00000010)
#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001)
......@@ -795,6 +817,11 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
#define MPI_RAID_VOL_TYPE_IS (0x00)
#define MPI_RAID_VOL_TYPE_IME (0x01)
#define MPI_RAID_VOL_TYPE_IM (0x02)
#define MPI_RAID_VOL_TYPE_RAID_5 (0x03)
#define MPI_RAID_VOL_TYPE_RAID_6 (0x04)
#define MPI_RAID_VOL_TYPE_RAID_10 (0x05)
#define MPI_RAID_VOL_TYPE_RAID_50 (0x06)
#define MPI_RAID_VOL_TYPE_UNKNOWN (0xFF)
/* IOC Page 2 Volume Flags values */
......@@ -820,13 +847,17 @@ typedef struct _CONFIG_PAGE_IOC_2
} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
IOCPage2_t, MPI_POINTER pIOCPage2_t;
#define MPI_IOCPAGE2_PAGEVERSION (0x02)
#define MPI_IOCPAGE2_PAGEVERSION (0x03)
/* IOC Page 2 Capabilities flags */
#define MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT (0x00000001)
#define MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT (0x00000002)
#define MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT (0x00000004)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT (0x00000008)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT (0x00000010)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT (0x00000020)
#define MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT (0x00000040)
#define MPI_IOCPAGE2_CAP_FLAGS_SES_SUPPORT (0x20000000)
#define MPI_IOCPAGE2_CAP_FLAGS_SAFTE_SUPPORT (0x40000000)
#define MPI_IOCPAGE2_CAP_FLAGS_CROSS_CHANNEL_SUPPORT (0x80000000)
......@@ -945,7 +976,7 @@ typedef struct _CONFIG_PAGE_BIOS_1
} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
#define MPI_BIOSPAGE1_PAGEVERSION (0x01)
#define MPI_BIOSPAGE1_PAGEVERSION (0x02)
/* values for the BiosOptions field */
#define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE (0x00000400)
......@@ -954,6 +985,8 @@ typedef struct _CONFIG_PAGE_BIOS_1
#define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS (0x00000001)
/* values for the IOCSettings field */
#define MPI_BIOSPAGE1_IOCSET_MASK_PORT_ENABLE_DELAY (0x00F00000)
#define MPI_BIOSPAGE1_IOCSET_SHIFT_PORT_ENABLE_DELAY (20)
#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE (0x00030000)
#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT (0x00000000)
#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT (0x00010000)
......@@ -1167,6 +1200,7 @@ typedef struct _CONFIG_PAGE_BIOS_2
#define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER (0x03)
#define MPI_BIOSPAGE2_FORM_FC_WWN (0x04)
#define MPI_BIOSPAGE2_FORM_SAS_WWN (0x05)
#define MPI_BIOSPAGE2_FORM_ENCLOSURE_SLOT (0x06)
/****************************************************************************
......@@ -1957,11 +1991,11 @@ typedef struct _RAID_VOL0_STATUS
RaidVol0Status_t, MPI_POINTER pRaidVol0Status_t;
/* RAID Volume Page 0 VolumeStatus defines */
#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01)
#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04)
#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08)
#define MPI_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL (0x10)
#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00)
#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01)
......@@ -2025,7 +2059,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x04)
#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x05)
/* values for RAID Volume Page 0 InactiveStatus field */
#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
......@@ -2104,6 +2138,8 @@ typedef struct _RAID_PHYS_DISK0_STATUS
#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01)
#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02)
#define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME (0x04)
#define MPI_PHYSDISK0_STATUS_FLAG_OPTIMAL_PREVIOUS (0x00)
#define MPI_PHYSDISK0_STATUS_FLAG_NOT_OPTIMAL_PREVIOUS (0x08)
#define MPI_PHYSDISK0_STATUS_ONLINE (0x00)
#define MPI_PHYSDISK0_STATUS_MISSING (0x01)
......@@ -2132,7 +2168,7 @@ typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
} CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x01)
#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x02)
typedef struct _RAID_PHYS_DISK1_PATH
......@@ -2263,7 +2299,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x02)
#define MPI_SASIOUNITPAGE0_PAGEVERSION (0x03)
/* values for SAS IO Unit Page 0 PortFlags */
#define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS (0x08)
......@@ -2299,6 +2335,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
#define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK (0x00000200)
#define MPI_SAS_IOUNIT0_DS_TABLE_LINK (0x00000400)
#define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE (0x00000800)
#define MPI_SAS_IOUNIT0_DS_MAX_SATA_TARGETS (0x00001000)
typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
......@@ -2336,6 +2373,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x04)
/* values for SAS IO Unit Page 1 ControlFlags */
#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX (0x4000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX (0x2000)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE (0x1000)
......@@ -2345,9 +2383,8 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT (9)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH (0x00)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT (0x01)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x10)
#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT (0x02)
#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED (0x0040)
#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED (0x0020)
......@@ -2390,7 +2427,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x03)
#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x04)
/* values for SAS IO Unit Page 2 Status field */
#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
......@@ -2406,6 +2443,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP (0x02)
#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT (0x10)
#define MPI_SAS_IOUNIT2_FLAGS_DA_STARTING_SLOT (0x20)
typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
......@@ -2584,11 +2622,19 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U64 PhysicalIdentifier; /* 08h */
U32 Reserved1; /* 10h */
U32 EnclosureMapping; /* 10h */
} CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2,
SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t;
#define MPI_SASDEVICE2_PAGEVERSION (0x00)
#define MPI_SASDEVICE2_PAGEVERSION (0x01)
/* defines for SAS Device Page 2 EnclosureMapping field */
#define MPI_SASDEVICE2_ENC_MAP_MASK_MISSING_COUNT (0x0000000F)
#define MPI_SASDEVICE2_ENC_MAP_SHIFT_MISSING_COUNT (0)
#define MPI_SASDEVICE2_ENC_MAP_MASK_NUM_SLOTS (0x000007F0)
#define MPI_SASDEVICE2_ENC_MAP_SHIFT_NUM_SLOTS (4)
#define MPI_SASDEVICE2_ENC_MAP_MASK_START_INDEX (0x001FF800)
#define MPI_SASDEVICE2_ENC_MAP_SHIFT_START_INDEX (11)
/****************************************************************************
......@@ -2598,7 +2644,8 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_2
typedef struct _CONFIG_PAGE_SAS_PHY_0
{
CONFIG_EXTENDED_PAGE_HEADER Header; /* 00h */
U32 Reserved1; /* 08h */
U16 OwnerDevHandle; /* 08h */
U16 Reserved1; /* 0Ah */
U64 SASAddress; /* 0Ch */
U16 AttachedDevHandle; /* 14h */
U8 AttachedPhyIdentifier; /* 16h */
......@@ -2607,12 +2654,12 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
U8 ProgrammedLinkRate; /* 20h */
U8 HwLinkRate; /* 21h */
U8 ChangeCount; /* 22h */
U8 Reserved3; /* 23h */
U8 Flags; /* 23h */
U32 PhyInfo; /* 24h */
} CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
#define MPI_SASPHY0_PAGEVERSION (0x00)
#define MPI_SASPHY0_PAGEVERSION (0x01)
/* values for SAS PHY Page 0 ProgrammedLinkRate field */
#define MPI_SAS_PHY0_PRATE_MAX_RATE_MASK (0xF0)
......@@ -2632,6 +2679,9 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
#define MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5 (0x08)
#define MPI_SAS_PHY0_HWRATE_MIN_RATE_3_0 (0x09)
/* values for SAS PHY Page 0 Flags field */
#define MPI_SAS_PHY0_FLAGS_SGPIO_DIRECT_ATTACH_ENC (0x01)
/* values for SAS PHY Page 0 PhyInfo field */
#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_ACTIVE (0x00004000)
#define MPI_SAS_PHY0_PHYINFO_SATA_PORT_SELECTOR (0x00002000)
......@@ -2690,7 +2740,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
} CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0,
SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t;
#define MPI_SASENCLOSURE0_PAGEVERSION (0x00)
#define MPI_SASENCLOSURE0_PAGEVERSION (0x01)
/* values for SAS Enclosure Page 0 Flags field */
#define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID (0x0020)
......@@ -2702,6 +2752,7 @@ typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO (0x0002)
#define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO (0x0003)
#define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE (0x0004)
#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO (0x0005)
/****************************************************************************
......
......@@ -6,17 +6,17 @@
Copyright (c) 2000-2005 LSI Logic Corporation.
---------------------------------------
Header Set Release Version: 01.05.09
Header Set Release Version: 01.05.10
Header Set Release Date: 03-11-05
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
mpi.h 01.05.07 01.05.06
mpi_ioc.h 01.05.08 01.05.07
mpi_cnfg.h 01.05.08 01.05.07
mpi_init.h 01.05.04 01.05.03
mpi_targ.h 01.05.04 01.05.03
mpi.h 01.05.08 01.05.07
mpi_ioc.h 01.05.09 01.05.08
mpi_cnfg.h 01.05.09 01.05.08
mpi_init.h 01.05.05 01.05.04
mpi_targ.h 01.05.05 01.05.04
mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02
......@@ -24,7 +24,7 @@
mpi_inb.h 01.05.01 01.05.01
mpi_sas.h 01.05.01 01.05.01
mpi_type.h 01.05.01 01.05.01
mpi_history.txt 01.05.09 01.05.08
mpi_history.txt 01.05.09 01.05.09
* Date Version Description
......@@ -88,6 +88,9 @@ mpi.h
* 03-11-05 01.05.07 Removed function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Removed EEDP IOCStatus codes.
* 06-24-05 01.05.08 Added function codes for SCSI IO 32 and
* TargetAssistExtended requests.
* Added EEDP IOCStatus codes.
* --------------------------------------------------------------------------
mpi_ioc.h
......@@ -159,6 +162,8 @@ mpi_ioc.h
* Reply and IOC Init Request.
* 03-11-05 01.05.08 Added family code for 1068E family.
* Removed IOCFacts Reply EEDP Capability bit.
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
* Added Max SATA Targets to SAS Discovery Error event.
* --------------------------------------------------------------------------
mpi_cnfg.h
......@@ -380,6 +385,23 @@ mpi_cnfg.h
* New physical mapping mode in SAS IO Unit Page 2.
* Added CONFIG_PAGE_SAS_ENCLOSURE_0.
* Added Slot and Enclosure fields to SAS Device Page 0.
* 06-24-05 01.05.09 Added EEDP defines to IOC Page 1.
* Added more RAID type defines to IOC Page 2.
* Added Port Enable Delay settings to BIOS Page 1.
* Added Bad Block Table Full define to RAID Volume Page 0.
* Added Previous State defines to RAID Physical Disk
* Page 0.
* Added Max Sata Targets define for DiscoveryStatus field
* of SAS IO Unit Page 0.
* Added Device Self Test to Control Flags of SAS IO Unit
* Page 1.
* Added Direct Attach Starting Slot Number define for SAS
* IO Unit Page 2.
* Added new fields in SAS Device Page 2 for enclosure
* mapping.
* Added OwnerDevHandle and Flags field to SAS PHY Page 0.
* Added IOC GPIO Flags define to SAS Enclosure Page 0.
* Fixed the value for MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT.
* --------------------------------------------------------------------------
mpi_init.h
......@@ -418,6 +440,8 @@ mpi_init.h
* Modified SCSI Enclosure Processor Request and Reply to
* support Enclosure/Slot addressing rather than WWID
* addressing.
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
* Added four new defines for SEP SlotStatus.
* --------------------------------------------------------------------------
mpi_targ.h
......@@ -461,6 +485,7 @@ mpi_targ.h
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
* 02-22-05 01.05.03 Changed a comment.
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
* 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
* --------------------------------------------------------------------------
mpi_fc.h
......@@ -571,20 +596,20 @@ mpi_type.h
mpi_history.txt Parts list history
Filename 01.05.09
---------- --------
mpi.h 01.05.07
mpi_ioc.h 01.05.08
mpi_cnfg.h 01.05.08
mpi_init.h 01.05.04
mpi_targ.h 01.05.04
mpi_fc.h 01.05.01
mpi_lan.h 01.05.01
mpi_raid.h 01.05.02
mpi_tool.h 01.05.03
mpi_inb.h 01.05.01
mpi_sas.h 01.05.01
mpi_type.h 01.05.01
Filename 01.05.10 01.05.09
---------- -------- --------
mpi.h 01.05.08 01.05.07
mpi_ioc.h 01.05.09 01.05.08
mpi_cnfg.h 01.05.09 01.05.08
mpi_init.h 01.05.05 01.05.04
mpi_targ.h 01.05.05 01.05.04
mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02
mpi_tool.h 01.05.03 01.05.03
mpi_inb.h 01.05.01 01.05.01
mpi_sas.h 01.05.01 01.05.01
mpi_type.h 01.05.01 01.05.01
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
---------- -------- -------- -------- -------- -------- --------
......
......@@ -6,7 +6,7 @@
* Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000
*
* mpi_init.h Version: 01.05.04
* mpi_init.h Version: 01.05.05
*
* Version History
* ---------------
......@@ -48,6 +48,8 @@
* Modified SCSI Enclosure Processor Request and Reply to
* support Enclosure/Slot addressing rather than WWID
* addressing.
* 06-24-05 01.05.05 Added SCSI IO 32 structures and defines.
* Added four new defines for SEP SlotStatus.
* --------------------------------------------------------------------------
*/
......@@ -202,6 +204,197 @@ typedef struct _MSG_SCSI_IO_REPLY
#define MPI_SCSI_TASKTAG_UNKNOWN (0xFFFF)
/****************************************************************************/
/* SCSI IO 32 messages and associated structures */
/****************************************************************************/
typedef struct
{
U8 CDB[20]; /* 00h */
U32 PrimaryReferenceTag; /* 14h */
U16 PrimaryApplicationTag; /* 18h */
U16 PrimaryApplicationTagMask; /* 1Ah */
U32 TransferLength; /* 1Ch */
} MPI_SCSI_IO32_CDB_EEDP32, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP32,
MpiScsiIo32CdbEedp32_t, MPI_POINTER pMpiScsiIo32CdbEedp32_t;
typedef struct
{
U8 CDB[16]; /* 00h */
U32 DataLength; /* 10h */
U32 PrimaryReferenceTag; /* 14h */
U16 PrimaryApplicationTag; /* 18h */
U16 PrimaryApplicationTagMask; /* 1Ah */
U32 TransferLength; /* 1Ch */
} MPI_SCSI_IO32_CDB_EEDP16, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_EEDP16,
MpiScsiIo32CdbEedp16_t, MPI_POINTER pMpiScsiIo32CdbEedp16_t;
typedef union
{
U8 CDB32[32];
MPI_SCSI_IO32_CDB_EEDP32 EEDP32;
MPI_SCSI_IO32_CDB_EEDP16 EEDP16;
SGE_SIMPLE_UNION SGE;
} MPI_SCSI_IO32_CDB_UNION, MPI_POINTER PTR_MPI_SCSI_IO32_CDB_UNION,
MpiScsiIo32Cdb_t, MPI_POINTER pMpiScsiIo32Cdb_t;
typedef struct
{
U8 TargetID; /* 00h */
U8 Bus; /* 01h */
U16 Reserved1; /* 02h */
U32 Reserved2; /* 04h */
} MPI_SCSI_IO32_BUS_TARGET_ID_FORM, MPI_POINTER PTR_MPI_SCSI_IO32_BUS_TARGET_ID_FORM,
MpiScsiIo32BusTargetIdForm_t, MPI_POINTER pMpiScsiIo32BusTargetIdForm_t;
typedef union
{
MPI_SCSI_IO32_BUS_TARGET_ID_FORM SCSIID;
U64 WWID;
} MPI_SCSI_IO32_ADDRESS, MPI_POINTER PTR_MPI_SCSI_IO32_ADDRESS,
MpiScsiIo32Address_t, MPI_POINTER pMpiScsiIo32Address_t;
typedef struct _MSG_SCSI_IO32_REQUEST
{
U8 Port; /* 00h */
U8 Reserved1; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Flags; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 LUN[8]; /* 0Ch */
U32 Control; /* 14h */
MPI_SCSI_IO32_CDB_UNION CDB; /* 18h */
U32 DataLength; /* 38h */
U32 BidirectionalDataLength; /* 3Ch */
U32 SecondaryReferenceTag; /* 40h */
U16 SecondaryApplicationTag; /* 44h */
U16 Reserved2; /* 46h */
U16 EEDPFlags; /* 48h */
U16 ApplicationTagTranslationMask; /* 4Ah */
U32 EEDPBlockSize; /* 4Ch */
MPI_SCSI_IO32_ADDRESS DeviceAddress; /* 50h */
U8 SGLOffset0; /* 58h */
U8 SGLOffset1; /* 59h */
U8 SGLOffset2; /* 5Ah */
U8 SGLOffset3; /* 5Bh */
U32 Reserved3; /* 5Ch */
U32 Reserved4; /* 60h */
U32 SenseBufferLowAddr; /* 64h */
SGE_IO_UNION SGL; /* 68h */
} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
/* SCSI IO 32 MsgFlags bits */
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH (0x01)
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_32 (0x00)
#define MPI_SCSIIO32_MSGFLGS_SENSE_WIDTH_64 (0x01)
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOCATION (0x02)
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_HOST (0x00)
#define MPI_SCSIIO32_MSGFLGS_SENSE_LOC_IOC (0x02)
#define MPI_SCSIIO32_MSGFLGS_CMD_DETERMINES_DATA_DIR (0x04)
#define MPI_SCSIIO32_MSGFLGS_SGL_OFFSETS_CHAINS (0x08)
#define MPI_SCSIIO32_MSGFLGS_MULTICAST (0x10)
#define MPI_SCSIIO32_MSGFLGS_BIDIRECTIONAL (0x20)
#define MPI_SCSIIO32_MSGFLGS_LARGE_CDB (0x40)
/* SCSI IO 32 Flags bits */
#define MPI_SCSIIO32_FLAGS_FORM_MASK (0x03)
#define MPI_SCSIIO32_FLAGS_FORM_SCSIID (0x00)
#define MPI_SCSIIO32_FLAGS_FORM_WWID (0x01)
/* SCSI IO 32 LUN fields */
#define MPI_SCSIIO32_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF)
#define MPI_SCSIIO32_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000)
#define MPI_SCSIIO32_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF)
#define MPI_SCSIIO32_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000)
#define MPI_SCSIIO32_LUN_LEVEL_1_WORD (0xFF00)
#define MPI_SCSIIO32_LUN_LEVEL_1_DWORD (0x0000FF00)
/* SCSI IO 32 Control bits */
#define MPI_SCSIIO32_CONTROL_DATADIRECTION_MASK (0x03000000)
#define MPI_SCSIIO32_CONTROL_NODATATRANSFER (0x00000000)
#define MPI_SCSIIO32_CONTROL_WRITE (0x01000000)
#define MPI_SCSIIO32_CONTROL_READ (0x02000000)
#define MPI_SCSIIO32_CONTROL_BIDIRECTIONAL (0x03000000)
#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_MASK (0xFC000000)
#define MPI_SCSIIO32_CONTROL_ADDCDBLEN_SHIFT (26)
#define MPI_SCSIIO32_CONTROL_TASKATTRIBUTE_MASK (0x00000700)
#define MPI_SCSIIO32_CONTROL_SIMPLEQ (0x00000000)
#define MPI_SCSIIO32_CONTROL_HEADOFQ (0x00000100)
#define MPI_SCSIIO32_CONTROL_ORDEREDQ (0x00000200)
#define MPI_SCSIIO32_CONTROL_ACAQ (0x00000400)
#define MPI_SCSIIO32_CONTROL_UNTAGGED (0x00000500)
#define MPI_SCSIIO32_CONTROL_NO_DISCONNECT (0x00000700)
#define MPI_SCSIIO32_CONTROL_TASKMANAGE_MASK (0x00FF0000)
#define MPI_SCSIIO32_CONTROL_OBSOLETE (0x00800000)
#define MPI_SCSIIO32_CONTROL_CLEAR_ACA_RSV (0x00400000)
#define MPI_SCSIIO32_CONTROL_TARGET_RESET (0x00200000)
#define MPI_SCSIIO32_CONTROL_LUN_RESET_RSV (0x00100000)
#define MPI_SCSIIO32_CONTROL_RESERVED (0x00080000)
#define MPI_SCSIIO32_CONTROL_CLR_TASK_SET_RSV (0x00040000)
#define MPI_SCSIIO32_CONTROL_ABORT_TASK_SET (0x00020000)
#define MPI_SCSIIO32_CONTROL_RESERVED2 (0x00010000)
/* SCSI IO 32 EEDPFlags */
#define MPI_SCSIIO32_EEDPFLAGS_MASK_OP (0x0007)
#define MPI_SCSIIO32_EEDPFLAGS_NOOP_OP (0x0000)
#define MPI_SCSIIO32_EEDPFLAGS_CHK_OP (0x0001)
#define MPI_SCSIIO32_EEDPFLAGS_STRIP_OP (0x0002)
#define MPI_SCSIIO32_EEDPFLAGS_CHKRM_OP (0x0003)
#define MPI_SCSIIO32_EEDPFLAGS_INSERT_OP (0x0004)
#define MPI_SCSIIO32_EEDPFLAGS_REPLACE_OP (0x0006)
#define MPI_SCSIIO32_EEDPFLAGS_CHKREGEN_OP (0x0007)
#define MPI_SCSIIO32_EEDPFLAGS_PASS_REF_TAG (0x0008)
#define MPI_SCSIIO32_EEDPFLAGS_8_9THS_MODE (0x0010)
#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_MASK (0x0700)
#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_GUARD (0x0100)
#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_REFTAG (0x0200)
#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_LBATAG (0x0400)
#define MPI_SCSIIO32_EEDPFLAGS_T10_CHK_SHIFT (8)
#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_APPTAG (0x1000)
#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_APPTAG (0x2000)
#define MPI_SCSIIO32_EEDPFLAGS_INC_SEC_REFTAG (0x4000)
#define MPI_SCSIIO32_EEDPFLAGS_INC_PRI_REFTAG (0x8000)
/* SCSIIO32 IO reply structure */
typedef struct _MSG_SCSIIO32_IO_REPLY
{
U8 Port; /* 00h */
U8 Reserved1; /* 01h */
U8 MsgLength; /* 02h */
U8 Function; /* 03h */
U8 CDBLength; /* 04h */
U8 SenseBufferLength; /* 05h */
U8 Flags; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U8 SCSIStatus; /* 0Ch */
U8 SCSIState; /* 0Dh */
U16 IOCStatus; /* 0Eh */
U32 IOCLogInfo; /* 10h */
U32 TransferCount; /* 14h */
U32 SenseCount; /* 18h */
U32 ResponseInfo; /* 1Ch */
U16 TaskTag; /* 20h */
U16 Reserved2; /* 22h */
U32 BidirectionalTransferCount; /* 24h */
} MSG_SCSIIO32_IO_REPLY, MPI_POINTER PTR_MSG_SCSIIO32_IO_REPLY,
SCSIIO32Reply_t, MPI_POINTER pSCSIIO32Reply_t;
/****************************************************************************/
/* SCSI Task Management messages */
/****************************************************************************/
......@@ -310,10 +503,14 @@ typedef struct _MSG_SEP_REQUEST
#define MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
#define MPI_SEP_REQ_SLOTSTATUS_REQ_CONSISTENCY_CHECK (0x00001000)
#define MPI_SEP_REQ_SLOTSTATUS_DISABLE (0x00002000)
#define MPI_SEP_REQ_SLOTSTATUS_REQ_RESERVED_DEVICE (0x00004000)
#define MPI_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000)
#define MPI_SEP_REQ_SLOTSTATUS_REQUEST_INSERT (0x00080000)
#define MPI_SEP_REQ_SLOTSTATUS_DO_NOT_MOVE (0x00400000)
#define MPI_SEP_REQ_SLOTSTATUS_ACTIVE (0x00800000)
#define MPI_SEP_REQ_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
#define MPI_SEP_REQ_SLOTSTATUS_A_ENABLE_BYPASS (0x08000000)
#define MPI_SEP_REQ_SLOTSTATUS_DEV_OFF (0x10000000)
......@@ -352,11 +549,15 @@ typedef struct _MSG_SEP_REPLY
#define MPI_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
#define MPI_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
#define MPI_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200)
#define MPI_SEP_REPLY_SLOTSTATUS_CONSISTENCY_CHECK (0x00001000)
#define MPI_SEP_REPLY_SLOTSTATUS_DISABLE (0x00002000)
#define MPI_SEP_REPLY_SLOTSTATUS_RESERVED_DEVICE (0x00004000)
#define MPI_SEP_REPLY_SLOTSTATUS_REPORT (0x00010000)
#define MPI_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000)
#define MPI_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000)
#define MPI_SEP_REPLY_SLOTSTATUS_INSERT_READY (0x00080000)
#define MPI_SEP_REPLY_SLOTSTATUS_DO_NOT_REMOVE (0x00400000)
#define MPI_SEP_REPLY_SLOTSTATUS_ACTIVE (0x00800000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_BYPASS_ENABLED (0x01000000)
#define MPI_SEP_REPLY_SLOTSTATUS_A_BYPASS_ENABLED (0x02000000)
#define MPI_SEP_REPLY_SLOTSTATUS_B_ENABLE_BYPASS (0x04000000)
......
......@@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
* mpi_ioc.h Version: 01.05.08
* mpi_ioc.h Version: 01.05.09
*
* Version History
* ---------------
......@@ -81,6 +81,8 @@
* Reply and IOC Init Request.
* 03-11-05 01.05.08 Added family code for 1068E family.
* Removed IOCFacts Reply EEDP Capability bit.
* 06-24-05 01.05.09 Added 5 new IOCFacts Reply IOCCapabilities bits.
* Added Max SATA Targets to SAS Discovery Error event.
* --------------------------------------------------------------------------
*/
......@@ -261,7 +263,11 @@ typedef struct _MSG_IOC_FACTS_REPLY
#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER (0x00000008)
#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER (0x00000010)
#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER (0x00000020)
#define MPI_IOCFACTS_CAPABILITY_EEDP (0x00000040)
#define MPI_IOCFACTS_CAPABILITY_BIDIRECTIONAL (0x00000080)
#define MPI_IOCFACTS_CAPABILITY_MULTICAST (0x00000100)
#define MPI_IOCFACTS_CAPABILITY_SCSIIO32 (0x00000200)
#define MPI_IOCFACTS_CAPABILITY_NO_SCSIIO16 (0x00000400)
/*****************************************************************************
......@@ -677,6 +683,7 @@ typedef struct _EVENT_DATA_DISCOVERY_ERROR
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE (0x00000200)
#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE (0x00000400)
#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS (0x00000800)
#define MPI_EVENT_DSCVRY_ERR_DS_MAX_SATA_TARGETS (0x00001000)
/*****************************************************************************
......
......@@ -6,7 +6,7 @@
* Title: MPI Target mode messages and structures
* Creation Date: June 22, 2000
*
* mpi_targ.h Version: 01.05.04
* mpi_targ.h Version: 01.05.05
*
* Version History
* ---------------
......@@ -53,6 +53,7 @@
* 10-05-04 01.05.02 MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
* 02-22-05 01.05.03 Changed a comment.
* 03-11-05 01.05.04 Removed TargetAssistExtended Request.
* 06-24-05 01.05.05 Added TargetAssistExtended structures and defines.
* --------------------------------------------------------------------------
*/
......@@ -370,6 +371,77 @@ typedef struct _MSG_TARGET_ERROR_REPLY
TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t;
/****************************************************************************/
/* Target Assist Extended Request */
/****************************************************************************/
typedef struct _MSG_TARGET_ASSIST_EXT_REQUEST
{
U8 StatusCode; /* 00h */
U8 TargetAssistFlags; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 QueueTag; /* 04h */
U8 Reserved1; /* 06h */
U8 MsgFlags; /* 07h */
U32 MsgContext; /* 08h */
U32 ReplyWord; /* 0Ch */
U8 LUN[8]; /* 10h */
U32 RelativeOffset; /* 18h */
U32 Reserved2; /* 1Ch */
U32 Reserved3; /* 20h */
U32 PrimaryReferenceTag; /* 24h */
U16 PrimaryApplicationTag; /* 28h */
U16 PrimaryApplicationTagMask; /* 2Ah */
U32 Reserved4; /* 2Ch */
U32 DataLength; /* 30h */
U32 BidirectionalDataLength; /* 34h */
U32 SecondaryReferenceTag; /* 38h */
U16 SecondaryApplicationTag; /* 3Ch */
U16 Reserved5; /* 3Eh */
U16 EEDPFlags; /* 40h */
U16 ApplicationTagTranslationMask; /* 42h */
U32 EEDPBlockSize; /* 44h */
U8 SGLOffset0; /* 48h */
U8 SGLOffset1; /* 49h */
U8 SGLOffset2; /* 4Ah */
U8 SGLOffset3; /* 4Bh */
U32 Reserved6; /* 4Ch */
SGE_IO_UNION SGL[1]; /* 50h */
} MSG_TARGET_ASSIST_EXT_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_EXT_REQUEST,
TargetAssistExtRequest_t, MPI_POINTER pTargetAssistExtRequest_t;
/* see the defines after MSG_TARGET_ASSIST_REQUEST for TargetAssistFlags */
/* defines for the MsgFlags field */
#define TARGET_ASSIST_EXT_MSGFLAGS_BIDIRECTIONAL (0x20)
#define TARGET_ASSIST_EXT_MSGFLAGS_MULTICAST (0x10)
#define TARGET_ASSIST_EXT_MSGFLAGS_SGL_OFFSET_CHAINS (0x08)
/* defines for the EEDPFlags field */
#define TARGET_ASSIST_EXT_EEDP_MASK_OP (0x0007)
#define TARGET_ASSIST_EXT_EEDP_NOOP_OP (0x0000)
#define TARGET_ASSIST_EXT_EEDP_CHK_OP (0x0001)
#define TARGET_ASSIST_EXT_EEDP_STRIP_OP (0x0002)
#define TARGET_ASSIST_EXT_EEDP_CHKRM_OP (0x0003)
#define TARGET_ASSIST_EXT_EEDP_INSERT_OP (0x0004)
#define TARGET_ASSIST_EXT_EEDP_REPLACE_OP (0x0006)
#define TARGET_ASSIST_EXT_EEDP_CHKREGEN_OP (0x0007)
#define TARGET_ASSIST_EXT_EEDP_PASS_REF_TAG (0x0008)
#define TARGET_ASSIST_EXT_EEDP_T10_CHK_MASK (0x0700)
#define TARGET_ASSIST_EXT_EEDP_T10_CHK_GUARD (0x0100)
#define TARGET_ASSIST_EXT_EEDP_T10_CHK_APPTAG (0x0200)
#define TARGET_ASSIST_EXT_EEDP_T10_CHK_REFTAG (0x0400)
#define TARGET_ASSIST_EXT_EEDP_T10_CHK_SHIFT (8)
#define TARGET_ASSIST_EXT_EEDP_INC_SEC_APPTAG (0x1000)
#define TARGET_ASSIST_EXT_EEDP_INC_PRI_APPTAG (0x2000)
#define TARGET_ASSIST_EXT_EEDP_INC_SEC_REFTAG (0x4000)
#define TARGET_ASSIST_EXT_EEDP_INC_PRI_REFTAG (0x8000)
/****************************************************************************/
/* Target Status Send Request */
/****************************************************************************/
......
此差异已折叠。
......@@ -915,7 +915,10 @@ struct scsi_cmnd;
typedef struct _x_config_parms {
struct list_head linkage; /* linked list */
struct timer_list timer; /* timer function for this request */
ConfigPageHeader_t *hdr;
union {
ConfigExtendedPageHeader_t *ehdr;
ConfigPageHeader_t *hdr;
} cfghdr;
dma_addr_t physAddr;
int wait_done; /* wait for this request */
u32 pageAddr; /* properly formatted */
......
......@@ -242,7 +242,7 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
/* Set the command status to GOOD if IOC Status is GOOD
* OR if SCSI I/O cmd and data underrun or recovered error.
*/
iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
iocStatus = le16_to_cpu(reply->u.reply.IOCStatus) & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SUCCESS)
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
......@@ -2324,7 +2324,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
hdr.PageLength = 0;
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
cfg.hdr = &hdr;
cfg.cfghdr.hdr = &hdr;
cfg.physAddr = -1;
cfg.pageAddr = 0;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
......@@ -2333,7 +2333,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
strncpy(karg.serial_number, " ", 24);
if (mpt_config(ioc, &cfg) == 0) {
if (cfg.hdr->PageLength > 0) {
if (cfg.cfghdr.hdr->PageLength > 0) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
......@@ -2479,7 +2479,7 @@ mptctl_hp_targetinfo(unsigned long arg)
hdr.PageNumber = 0;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &hdr;
cfg.cfghdr.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
cfg.timeout = 0;
......@@ -2527,15 +2527,15 @@ mptctl_hp_targetinfo(unsigned long arg)
hdr.PageNumber = 3;
hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &hdr;
cfg.cfghdr.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.dir = 0;
cfg.timeout = 0;
cfg.physAddr = -1;
if ((mpt_config(ioc, &cfg) == 0) && (cfg.hdr->PageLength > 0)) {
if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
/* Issue the second config page request */
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
data_sz = (int) cfg.hdr->PageLength * 4;
data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
pg3_alloc = (SCSIDevicePage3_t *) pci_alloc_consistent(
ioc->pcidev, data_sz, &page_dma);
if (pg3_alloc) {
......
......@@ -281,12 +281,12 @@ mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
chain_idx = offset / ioc->req_sz;
rc = SUCCESS;
dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
ioc->name, *retIndex, chainBuf));
dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
} else {
rc = FAILED;
chain_idx = MPT_HOST_NO_CHAIN;
dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
ioc->name));
}
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
......@@ -432,7 +432,7 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
*/
pReq->ChainOffset = 0;
RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
dsgprintk((MYIOC_s_ERR_FMT
dsgprintk((MYIOC_s_INFO_FMT
"Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
ioc->RequestNB[req_idx] = RequestNB;
}
......@@ -491,11 +491,12 @@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
/* NOTE: psge points to the beginning of the chain element
* in current buffer. Get a chain buffer.
*/
dsgprintk((MYIOC_s_INFO_FMT
"calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
ioc->name, pReq->CDB[0], SCpnt));
if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
dfailprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
ioc->name, pReq->CDB[0], SCpnt));
return FAILED;
}
/* Update the tracking arrays.
* If chainSge == NULL, update ReqToChain, else ChainToChain
......@@ -577,14 +578,20 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
dmfprintk((MYIOC_s_INFO_FMT
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
ioc->name, mf, mr, sc, req_idx));
sc->result = DID_OK << 16; /* Set default reply as OK */
pScsiReq = (SCSIIORequest_t *) mf;
pScsiReply = (SCSIIOReply_t *) mr;
if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
dmfprintk((MYIOC_s_INFO_FMT
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
}else{
dmfprintk((MYIOC_s_INFO_FMT
"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
ioc->name, mf, mr, sc, req_idx));
}
if (pScsiReply == NULL) {
/* special context reply handling */
;
......@@ -658,8 +665,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
} else if ( xfer_cnt == 0 ) {
/* A CRC Error causes this condition; retry */
sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
/* A CRC Error causes this condition; retry */
sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
(CHECK_CONDITION << 1);
sc->sense_buffer[0] = 0x70;
sc->sense_buffer[2] = NO_SENSE;
......@@ -668,7 +675,9 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
} else {
sc->result = DID_SOFT_ERROR << 16;
}
dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
dreplyprintk((KERN_NOTICE
"RESIDUAL_MISMATCH: result=%x on id=%d\n",
sc->result, sc->device->id));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
......@@ -796,7 +805,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 1;
}
/*
* mptscsih_flush_running_cmds - For each command found, search
* Scsi_Host instance taskQ and reply to OS.
......@@ -1017,7 +1025,7 @@ mptscsih_remove(struct pci_dev *pdev)
scsi_host_put(host);
mpt_detach(pdev);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -1072,7 +1080,7 @@ mptscsih_resume(struct pci_dev *pdev)
MPT_SCSI_HOST *hd;
mpt_resume(pdev);
if(!host)
return 0;
......@@ -1214,8 +1222,8 @@ mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off
int size = 0;
if (func) {
/*
* write is not supported
/*
* write is not supported
*/
} else {
if (start)
......@@ -1535,17 +1543,17 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
*/
if (mptscsih_tm_pending_wait(hd) == FAILED) {
if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
......@@ -1631,8 +1639,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
hd->ioc->name));
//return FAILED;
return -999;
return FAILED;
}
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
hd->ioc->name, mf));
......@@ -1661,9 +1668,8 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->TaskMsgContext = ctx2abort;
dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
hd->ioc->name, ctx2abort, type));
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
hd->ioc->name, ctx2abort, type));
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
......@@ -1902,13 +1908,13 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
/* If we can't locate the host to reset, then we failed. */
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt ) );
return FAILED;
}
printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
/* If our attempts to reset the host failed, then return a failed
......@@ -1924,7 +1930,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
hd->tmState = TM_STATE_NONE;
}
dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
"Status = %s\n",
(status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
......@@ -1951,8 +1957,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
if (hd->tmState == TM_STATE_NONE) {
hd->tmState = TM_STATE_IN_PROGRESS;
hd->tmPending = 1;
status = SUCCESS;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
status = SUCCESS;
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
......@@ -1980,7 +1986,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if(hd->tmPending == 0) {
status = SUCCESS;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
......@@ -2318,10 +2324,10 @@ mptscsih_slave_configure(struct scsi_device *device)
if (pTarget == NULL) {
/* Driver doesn't know about this device.
* Kernel may generate a "Dummy Lun 0" which
* may become a real Lun if a
* may become a real Lun if a
* "scsi add-single-device" command is executed
* while the driver is active (hot-plug a
* device). LSI Raid controllers need
* while the driver is active (hot-plug a
* device). LSI Raid controllers need
* queue_depth set to DEV_HIGH for this reason.
*/
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
......@@ -2691,7 +2697,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
* If the peripheral qualifier filter is enabled then if the target reports a 0x1
* (i.e. The targer is capable of supporting the specified peripheral device type
* on this logical unit; however, the physical device is not currently connected
* to this logical unit) it will be converted to a 0x3 (i.e. The target is not
* to this logical unit) it will be converted to a 0x3 (i.e. The target is not
* capable of supporting a physical device on this logical unit). This is to work
* around a bug in th emid-layer in some distributions in which the mid-layer will
* continue to try to communicate to the LUN and evntually create a dummy LUN.
......@@ -3194,8 +3200,8 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
ioc->name));
dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
ioc->name));
return -EAGAIN;
}
......@@ -3289,7 +3295,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
/* Get a MF for this command.
*/
if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
ioc->name));
return -EAGAIN;
}
......@@ -3447,7 +3453,7 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
* some type of error occurred.
*/
MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
completionCode = MPT_SCANDV_GOOD;
else
completionCode = MPT_SCANDV_SOME_ERROR;
......@@ -3955,7 +3961,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
header1.PageLength = ioc->spi_data.sdp1length;
header1.PageNumber = 1;
header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
cfg.hdr = &header1;
cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
......@@ -3996,9 +4002,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
"offset=0 negoFlags=%x request=%x config=%x\n",
id, flags, requested, configuration));
pcfg1Data->RequestedParameters = le32_to_cpu(requested);
pcfg1Data->RequestedParameters = cpu_to_le32(requested);
pcfg1Data->Reserved = 0;
pcfg1Data->Configuration = le32_to_cpu(configuration);
pcfg1Data->Configuration = cpu_to_le32(configuration);
cfg.pageAddr = (bus<<8) | id;
mpt_config(hd->ioc, &cfg);
}
......@@ -4353,7 +4359,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Prep cfg structure
*/
cfg.pageAddr = (bus<<8) | id;
cfg.hdr = NULL;
cfg.cfghdr.hdr = NULL;
/* Prep SDP0 header
*/
......@@ -4399,7 +4405,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
cfg1_dma_addr = dvbuf_dma + sz;
/* Skip this ID? Set cfg.hdr to force config page write
/* Skip this ID? Set cfg.cfghdr.hdr to force config page write
*/
{
ScsiCfgData *pspi_data = &hd->ioc->spi_data;
......@@ -4417,7 +4423,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
dv.cmd = MPT_SET_MAX;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
cfg.hdr = &header1;
cfg.cfghdr.hdr = &header1;
/* Save the final negotiated settings to
* SCSI device page 1.
......@@ -4483,7 +4489,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
dv.cmd = MPT_SET_MIN;
mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
cfg.hdr = &header1;
cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
......@@ -4596,8 +4602,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if ((pbuf1[56] & 0x02) == 0) {
pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
ioc->name, id, pbuf1[56]));
}
}
......@@ -4637,7 +4643,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
u32 sdp0_info;
u32 sdp0_nego;
cfg.hdr = &header0;
cfg.cfghdr.hdr = &header0;
cfg.physAddr = cfg0_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
......@@ -4673,7 +4679,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
if (!firstPass)
doFallback = 1;
} else {
ddvprintk((MYIOC_s_NOTE_FMT
ddvprintk((MYIOC_s_NOTE_FMT
"DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
mptscsih_initTarget(hd,
......@@ -4689,8 +4695,8 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
} else if (rc == MPT_SCANDV_ISSUE_SENSE)
doFallback = 1; /* set fallback flag */
else if ((rc == MPT_SCANDV_DID_RESET) ||
(rc == MPT_SCANDV_SENSE) ||
else if ((rc == MPT_SCANDV_DID_RESET) ||
(rc == MPT_SCANDV_SENSE) ||
(rc == MPT_SCANDV_FALLBACK))
doFallback = 1; /* set fallback flag */
else
......@@ -4722,7 +4728,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
* 4) release
* 5) update nego parms to target struct
*/
cfg.hdr = &header1;
cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
......@@ -5121,12 +5127,12 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Set if cfg1_dma_addr contents is valid
*/
if ((cfg.hdr != NULL) && (retcode == 0)){
if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
/* If disk, not U320, disable QAS
*/
if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
ddvprintk((MYIOC_s_NOTE_FMT
ddvprintk((MYIOC_s_NOTE_FMT
"noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
}
......@@ -5137,7 +5143,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
* skip save of the final negotiated settings to
* SCSI device page 1.
*
cfg.hdr = &header1;
cfg.cfghdr.hdr = &header1;
cfg.physAddr = cfg1_dma_addr;
cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
cfg.dir = 1;
......@@ -5248,7 +5254,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
/* Update tmax values with those from Device Page 0.*/
pPage0 = (SCSIDevicePage0_t *) pPage;
if (pPage0) {
val = cpu_to_le32(pPage0->NegotiatedParameters);
val = le32_to_cpu(pPage0->NegotiatedParameters);
dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
......@@ -5276,12 +5282,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
dv->now.offset, &val, &configuration, dv->now.flags);
dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
pPage1->Configuration = cpu_to_le32(configuration);
}
ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
break;
......@@ -5301,9 +5307,9 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
offset, &val, &configuration, negoFlags);
dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
id, width, factor, offset, negoFlags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
pPage1->Configuration = cpu_to_le32(configuration);
}
ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
id, width, factor, offset, val, configuration, negoFlags));
......@@ -5377,12 +5383,12 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
if (pPage1) {
mptscsih_setDevicePage1Flags (width, factor, offset, &val,
&configuration, dv->now.flags);
dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
id, width, offset, factor, dv->now.flags, val, configuration));
pPage1->RequestedParameters = le32_to_cpu(val);
pPage1->RequestedParameters = cpu_to_le32(val);
pPage1->Reserved = 0;
pPage1->Configuration = le32_to_cpu(configuration);
pPage1->Configuration = cpu_to_le32(configuration);
}
ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
......
......@@ -162,15 +162,15 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
u8 *mem;
int error=0;
int r;
if ((r = mpt_attach(pdev,id)) != 0)
return r;
ioc = pci_get_drvdata(pdev);
ioc->DoneCtx = mptspiDoneCtx;
ioc->TaskCtx = mptspiTaskCtx;
ioc->InternalCtx = mptspiInternalCtx;
/* Added sanity check on readiness of the MPT adapter.
*/
if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
......
......@@ -1499,22 +1499,43 @@ static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
return 0;
} /* End tw_scsiop_inquiry() */
static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
void *data, unsigned int len)
{
struct scsi_cmnd *cmd = tw_dev->srb[request_id];
void *buf;
unsigned int transfer_len;
if (cmd->use_sg) {
struct scatterlist *sg =
(struct scatterlist *)cmd->request_buffer;
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
transfer_len = min(sg->length, len);
} else {
buf = cmd->request_buffer;
transfer_len = min(cmd->request_bufflen, len);
}
memcpy(buf, data, transfer_len);
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *)cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
/* This function is called by the isr to complete an inquiry command */
static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
{
unsigned char *is_unit_present;
unsigned char *request_buffer;
unsigned char request_buffer[36];
TW_Param *param;
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
/* Fill request buffer */
if (tw_dev->srb[request_id]->request_buffer == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
return 1;
}
request_buffer = tw_dev->srb[request_id]->request_buffer;
memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
memset(request_buffer, 0, sizeof(request_buffer));
request_buffer[0] = TYPE_DISK; /* Peripheral device type */
request_buffer[1] = 0; /* Device type modifier */
request_buffer[2] = 0; /* No ansi/iso compliance */
......@@ -1522,6 +1543,8 @@ static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_i
memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
tw_transfer_internal(tw_dev, request_id, request_buffer,
sizeof(request_buffer));
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
if (param == NULL) {
......@@ -1612,7 +1635,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
{
TW_Param *param;
unsigned char *flags;
unsigned char *request_buffer;
unsigned char request_buffer[8];
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
......@@ -1622,8 +1645,7 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
return 1;
}
flags = (char *)&(param->data[0]);
request_buffer = tw_dev->srb[request_id]->buffer;
memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
memset(request_buffer, 0, sizeof(request_buffer));
request_buffer[0] = 0xf; /* mode data length */
request_buffer[1] = 0; /* default medium type */
......@@ -1635,6 +1657,8 @@ static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int reques
request_buffer[6] = 0x4; /* WCE on */
else
request_buffer[6] = 0x0; /* WCE off */
tw_transfer_internal(tw_dev, request_id, request_buffer,
sizeof(request_buffer));
return 0;
} /* End tw_scsiop_mode_sense_complete() */
......@@ -1701,17 +1725,12 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
{
unsigned char *param_data;
u32 capacity;
char *buff;
char buff[8];
TW_Param *param;
dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
buff = tw_dev->srb[request_id]->request_buffer;
if (buff == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
return 1;
}
memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
memset(buff, 0, sizeof(buff));
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
if (param == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
......@@ -1739,6 +1758,8 @@ static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int req
buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
buff[7] = TW_BLOCK_SIZE & 0xff;
tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
return 0;
} /* End tw_scsiop_read_capacity_complete() */
......
menu "SCSI device support"
config RAID_ATTRS
tristate "RAID Transport Class"
default n
---help---
Provides RAID
config SCSI
tristate "SCSI device support"
---help---
......
......@@ -22,6 +22,8 @@ subdir-$(CONFIG_PCMCIA) += pcmcia
obj-$(CONFIG_SCSI) += scsi_mod.o
obj-$(CONFIG_RAID_ATTRS) += raid_class.o
# --- NOTE ORDERING HERE ---
# For kernel non-modular link, transport attributes need to
# be initialised before drivers
......
......@@ -133,6 +133,7 @@ struct inquiry_data {
static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
#ifdef AAC_DETAILED_STATUS_INFO
static char *aac_get_status_string(u32 status);
......@@ -348,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd)
spin_unlock_irqrestore(host->host_lock, cpu_flags);
}
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{
void *buf;
unsigned int transfer_len;
struct scatterlist *sg = scsicmd->request_buffer;
if (scsicmd->use_sg) {
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
transfer_len = min(sg->length, len + offset);
} else {
buf = scsicmd->request_buffer;
transfer_len = min(scsicmd->request_bufflen, len + offset);
}
memcpy(buf + offset, data, transfer_len - offset);
if (scsicmd->use_sg)
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
static void get_container_name_callback(void *context, struct fib * fibptr)
{
struct aac_get_name_resp * get_name_reply;
......@@ -363,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
/* Failure is irrelevant, using default value instead */
if ((le32_to_cpu(get_name_reply->status) == CT_OK)
&& (get_name_reply->data[0] != '\0')) {
int count;
char * dp;
char * sp = get_name_reply->data;
char *sp = get_name_reply->data;
sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
while (*sp == ' ')
++sp;
count = sizeof(((struct inquiry_data *)NULL)->inqd_pid);
dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid;
if (*sp) do {
*dp++ = (*sp) ? *sp++ : ' ';
} while (--count > 0);
if (*sp) {
char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
int count = sizeof(d);
char *dp = d;
do {
*dp++ = (*sp) ? *sp++ : ' ';
} while (--count > 0);
aac_internal_transfer(scsicmd, d,
offsetof(struct inquiry_data, inqd_pid), sizeof(d));
}
}
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
fib_complete(fibptr);
......@@ -777,34 +803,36 @@ int aac_get_adapter_info(struct aac_dev* dev)
/*
* 57 scatter gather elements
*/
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write) + sizeof(struct sgmap)) /
sizeof(struct sgmap);
if (dev->dac_support) {
/*
* 38 scatter gather elements
*/
dev->scsi_host_ptr->sg_tablesize =
(dev->max_fib_size -
if (!(dev->raw_io_interface)) {
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write64) +
sizeof(struct sgmap64)) /
sizeof(struct sgmap64);
}
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
/*
* Worst case size that could cause sg overflow when
* we break up SG elements that are larger than 64KB.
* Would be nice if we could tell the SCSI layer what
* the maximum SG element size can be. Worst case is
* (sg_tablesize-1) 4KB elements with one 64KB
* element.
* 32bit -> 468 or 238KB 64bit -> 424 or 212KB
*/
dev->scsi_host_ptr->max_sectors =
(dev->scsi_host_ptr->sg_tablesize * 8) + 112;
sizeof(struct aac_write) + sizeof(struct sgmap)) /
sizeof(struct sgmap);
if (dev->dac_support) {
/*
* 38 scatter gather elements
*/
dev->scsi_host_ptr->sg_tablesize =
(dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write64) +
sizeof(struct sgmap64)) /
sizeof(struct sgmap64);
}
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
/*
* Worst case size that could cause sg overflow when
* we break up SG elements that are larger than 64KB.
* Would be nice if we could tell the SCSI layer what
* the maximum SG element size can be. Worst case is
* (sg_tablesize-1) 4KB elements with one 64KB
* element.
* 32bit -> 468 or 238KB 64bit -> 424 or 212KB
*/
dev->scsi_host_ptr->max_sectors =
(dev->scsi_host_ptr->sg_tablesize * 8) + 112;
}
}
fib_complete(fibptr);
......@@ -814,12 +842,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
static void read_callback(void *context, struct fib * fibptr)
static void io_callback(void *context, struct fib * fibptr)
{
struct aac_dev *dev;
struct aac_read_reply *readreply;
struct scsi_cmnd *scsicmd;
u32 lba;
u32 cid;
scsicmd = (struct scsi_cmnd *) context;
......@@ -827,8 +854,7 @@ static void read_callback(void *context, struct fib * fibptr)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
dprintk((KERN_DEBUG "io_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3], jiffies));
if (fibptr == NULL)
BUG();
......@@ -847,7 +873,7 @@ static void read_callback(void *context, struct fib * fibptr)
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
else {
#ifdef AAC_DETAILED_STATUS_INFO
printk(KERN_WARNING "read_callback: io failed, status = %d\n",
printk(KERN_WARNING "io_callback: io failed, status = %d\n",
le32_to_cpu(readreply->status));
#endif
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
......@@ -867,53 +893,6 @@ static void read_callback(void *context, struct fib * fibptr)
aac_io_done(scsicmd);
}
static void write_callback(void *context, struct fib * fibptr)
{
struct aac_dev *dev;
struct aac_write_reply *writereply;
struct scsi_cmnd *scsicmd;
u32 lba;
u32 cid;
scsicmd = (struct scsi_cmnd *) context;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
if (fibptr == NULL)
BUG();
if(scsicmd->use_sg)
pci_unmap_sg(dev->pdev,
(struct scatterlist *)scsicmd->buffer,
scsicmd->use_sg,
scsicmd->sc_data_direction);
else if(scsicmd->request_bufflen)
pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
scsicmd->request_bufflen,
scsicmd->sc_data_direction);
writereply = (struct aac_write_reply *) fib_data(fibptr);
if (le32_to_cpu(writereply->status) == ST_OK)
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
else {
printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
HARDWARE_ERROR,
SENCODE_INTERNAL_TARGET_FAILURE,
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
0, 0);
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
sizeof(struct sense_data));
}
fib_complete(fibptr);
fib_free(fibptr);
aac_io_done(scsicmd);
}
static int aac_read(struct scsi_cmnd * scsicmd, int cid)
{
u32 lba;
......@@ -954,7 +933,32 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
fib_init(cmd_fibcontext);
if (dev->dac_support == 1) {
if (dev->raw_io_interface) {
struct aac_raw_io *readcmd;
readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
readcmd->block[0] = cpu_to_le32(lba);
readcmd->block[1] = 0;
readcmd->count = cpu_to_le32(count<<9);
readcmd->cid = cpu_to_le16(cid);
readcmd->flags = cpu_to_le16(1);
readcmd->bpTotal = 0;
readcmd->bpComplete = 0;
aac_build_sgraw(scsicmd, &readcmd->sg);
fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
BUG();
/*
* Now send the Fib to the adapter
*/
status = fib_send(ContainerRawIo,
cmd_fibcontext,
fibsize,
FsaNormal,
0, 1,
(fib_callback) io_callback,
(void *) scsicmd);
} else if (dev->dac_support == 1) {
struct aac_read64 *readcmd;
readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
readcmd->command = cpu_to_le32(VM_CtHostRead64);
......@@ -968,7 +972,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
fibsize = sizeof(struct aac_read64) +
((le32_to_cpu(readcmd->sg.count) - 1) *
sizeof (struct sgentry64));
BUG_ON (fibsize > (sizeof(struct hw_fib) -
BUG_ON (fibsize > (dev->max_fib_size -
sizeof(struct aac_fibhdr)));
/*
* Now send the Fib to the adapter
......@@ -978,7 +982,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
fibsize,
FsaNormal,
0, 1,
(fib_callback) read_callback,
(fib_callback) io_callback,
(void *) scsicmd);
} else {
struct aac_read *readcmd;
......@@ -1002,7 +1006,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
fibsize,
FsaNormal,
0, 1,
(fib_callback) read_callback,
(fib_callback) io_callback,
(void *) scsicmd);
}
......@@ -1061,7 +1065,32 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
}
fib_init(cmd_fibcontext);
if(dev->dac_support == 1) {
if (dev->raw_io_interface) {
struct aac_raw_io *writecmd;
writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
writecmd->block[0] = cpu_to_le32(lba);
writecmd->block[1] = 0;
writecmd->count = cpu_to_le32(count<<9);
writecmd->cid = cpu_to_le16(cid);
writecmd->flags = 0;
writecmd->bpTotal = 0;
writecmd->bpComplete = 0;
aac_build_sgraw(scsicmd, &writecmd->sg);
fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
BUG();
/*
* Now send the Fib to the adapter
*/
status = fib_send(ContainerRawIo,
cmd_fibcontext,
fibsize,
FsaNormal,
0, 1,
(fib_callback) io_callback,
(void *) scsicmd);
} else if (dev->dac_support == 1) {
struct aac_write64 *writecmd;
writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
writecmd->command = cpu_to_le32(VM_CtHostWrite64);
......@@ -1085,7 +1114,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
fibsize,
FsaNormal,
0, 1,
(fib_callback) write_callback,
(fib_callback) io_callback,
(void *) scsicmd);
} else {
struct aac_write *writecmd;
......@@ -1111,7 +1140,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
fibsize,
FsaNormal,
0, 1,
(fib_callback) write_callback,
(fib_callback) io_callback,
(void *) scsicmd);
}
......@@ -1340,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
switch (scsicmd->cmnd[0]) {
case INQUIRY:
{
struct inquiry_data *inq_data_ptr;
struct inquiry_data inq_data;
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer;
memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
memset(&inq_data, 0, sizeof (struct inquiry_data));
inq_data_ptr->inqd_ver = 2; /* claim compliance to SCSI-2 */
inq_data_ptr->inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */
inq_data_ptr->inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
inq_data_ptr->inqd_len = 31;
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
inq_data.inqd_dtq = 0x80; /* set RMB bit to one indicating that the medium is removable */
inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
inq_data.inqd_len = 31;
/*Format for "pad2" is RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
inq_data_ptr->inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */
inq_data.inqd_pad2= 0x32 ; /*WBus16|Sync|CmdQue */
/*
* Set the Vendor, Product, and Revision Level
* see: <vendor>.c i.e. aac.c
*/
if (scsicmd->device->id == host->this_id) {
setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *)));
inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */
setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
return 0;
}
setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type);
inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
return aac_get_container_name(scsicmd, cid);
}
case READ_CAPACITY:
{
u32 capacity;
char *cp;
char cp[8];
dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
if (fsa_dev_ptr[cid].size <= 0x100000000LL)
capacity = fsa_dev_ptr[cid].size - 1;
else
capacity = (u32)-1;
cp = scsicmd->request_buffer;
cp[0] = (capacity >> 24) & 0xff;
cp[1] = (capacity >> 16) & 0xff;
cp[2] = (capacity >> 8) & 0xff;
......@@ -1386,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[5] = 0;
cp[6] = 2;
cp[7] = 0;
aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
......@@ -1395,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case MODE_SENSE:
{
char *mode_buf;
char mode_buf[4];
dprintk((KERN_DEBUG "MODE SENSE command.\n"));
mode_buf = scsicmd->request_buffer;
mode_buf[0] = 3; /* Mode data length */
mode_buf[1] = 0; /* Medium type - default */
mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */
mode_buf[3] = 0; /* Block descriptor length */
aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
......@@ -1411,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
case MODE_SENSE_10:
{
char *mode_buf;
char mode_buf[8];
dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
mode_buf = scsicmd->request_buffer;
mode_buf[0] = 0; /* Mode data length (MSB) */
mode_buf[1] = 6; /* Mode data length (LSB) */
mode_buf[2] = 0; /* Medium type - default */
......@@ -1423,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mode_buf[5] = 0; /* reserved */
mode_buf[6] = 0; /* Block descriptor length (MSB) */
mode_buf[7] = 0; /* Block descriptor length (LSB) */
aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
......@@ -1894,7 +1925,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
srbcmd->id = cpu_to_le32(scsicmd->device->id);
srbcmd->lun = cpu_to_le32(scsicmd->device->lun);
srbcmd->flags = cpu_to_le32(flag);
timeout = (scsicmd->timeout-jiffies)/HZ;
timeout = scsicmd->timeout_per_command/HZ;
if(timeout == 0){
timeout = 1;
}
......@@ -2077,6 +2108,76 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
return byte_count;
}
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg)
{
struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
unsigned long byte_count = 0;
// Get rid of old data
psg->count = 0;
psg->sg[0].next = 0;
psg->sg[0].prev = 0;
psg->sg[0].addr[0] = 0;
psg->sg[0].addr[1] = 0;
psg->sg[0].count = 0;
psg->sg[0].flags = 0;
if (scsicmd->use_sg) {
struct scatterlist *sg;
int i;
int sg_count;
sg = (struct scatterlist *) scsicmd->request_buffer;
sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
scsicmd->sc_data_direction);
for (i = 0; i < sg_count; i++) {
int count = sg_dma_len(sg);
u64 addr = sg_dma_address(sg);
psg->sg[i].next = 0;
psg->sg[i].prev = 0;
psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));
psg->sg[i].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
psg->sg[i].count = cpu_to_le32(count);
psg->sg[i].flags = 0;
byte_count += count;
sg++;
}
psg->count = cpu_to_le32(sg_count);
/* hba wants the size to be exact */
if(byte_count > scsicmd->request_bufflen){
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
(byte_count - scsicmd->request_bufflen);
psg->sg[i-1].count = cpu_to_le32(temp);
byte_count = scsicmd->request_bufflen;
}
/* Check for command underflow */
if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",
byte_count, scsicmd->underflow);
}
}
else if(scsicmd->request_bufflen) {
int count;
u64 addr;
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
scsicmd->request_buffer,
scsicmd->request_bufflen,
scsicmd->sc_data_direction);
addr = scsicmd->SCp.dma_handle;
count = scsicmd->request_bufflen;
psg->count = cpu_to_le32(1);
psg->sg[0].next = 0;
psg->sg[0].prev = 0;
psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32));
psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
psg->sg[0].count = cpu_to_le32(count);
psg->sg[0].flags = 0;
byte_count = scsicmd->request_bufflen;
}
return byte_count;
}
#ifdef AAC_DETAILED_STATUS_INFO
struct aac_srb_status_info {
......
......@@ -110,6 +110,22 @@ struct user_sgentry64 {
u32 count; /* Length. */
};
struct sgentryraw {
__le32 next; /* reserved for F/W use */
__le32 prev; /* reserved for F/W use */
__le32 addr[2];
__le32 count;
__le32 flags; /* reserved for F/W use */
};
struct user_sgentryraw {
u32 next; /* reserved for F/W use */
u32 prev; /* reserved for F/W use */
u32 addr[2];
u32 count;
u32 flags; /* reserved for F/W use */
};
/*
* SGMAP
*
......@@ -137,6 +153,16 @@ struct user_sgmap64 {
struct user_sgentry64 sg[1];
};
struct sgmapraw {
__le32 count;
struct sgentryraw sg[1];
};
struct user_sgmapraw {
u32 count;
struct user_sgentryraw sg[1];
};
struct creation_info
{
u8 buildnum; /* e.g., 588 */
......@@ -351,6 +377,7 @@ struct hw_fib {
*/
#define ContainerCommand 500
#define ContainerCommand64 501
#define ContainerRawIo 502
/*
* Cluster Commands
*/
......@@ -456,6 +483,7 @@ struct adapter_ops
{
void (*adapter_interrupt)(struct aac_dev *dev);
void (*adapter_notify)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
int (*adapter_check_health)(struct aac_dev *dev);
};
......@@ -981,6 +1009,9 @@ struct aac_dev
u8 nondasd_support;
u8 dac_support;
u8 raid_scsi_mode;
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
u8 printf_enabled;
};
......@@ -990,6 +1021,9 @@ struct aac_dev
#define aac_adapter_notify(dev, event) \
(dev)->a_ops.adapter_notify(dev, event)
#define aac_adapter_disable_int(dev) \
(dev)->a_ops.adapter_disable_int(dev)
#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
......@@ -1156,6 +1190,17 @@ struct aac_write_reply
__le32 committed;
};
struct aac_raw_io
{
__le32 block[2];
__le32 count;
__le16 cid;
__le16 flags; /* 00 W, 01 R */
__le16 bpTotal; /* reserved for F/W use */
__le16 bpComplete; /* reserved for F/W use */
struct sgmapraw sg;
};
#define CT_FLUSH_CACHE 129
struct aac_synchronize {
__le32 command; /* VM_ContainerConfig */
......@@ -1196,7 +1241,7 @@ struct aac_srb
};
/*
* This and assocated data structs are used by the
* This and associated data structs are used by the
* ioctl caller and are in cpu order.
*/
struct user_aac_srb
......@@ -1508,11 +1553,12 @@ struct fib_ioctl
struct revision
{
u32 compat;
u32 version;
u32 build;
__le32 compat;
__le32 version;
__le32 build;
};
/*
* Ugly - non Linux like ioctl coding for back compat.
*/
......@@ -1733,3 +1779,4 @@ int aac_get_adapter_info(struct aac_dev* dev);
int aac_send_shutdown(struct aac_dev *dev);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
......@@ -287,7 +287,6 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
kfree(fib->hw_fib);
kfree(fib);
status = 0;
fibctx->jiffies = jiffies/HZ;
} else {
spin_unlock_irqrestore(&dev->fib_lock, flags);
if (f.wait) {
......@@ -302,6 +301,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
status = -EAGAIN;
}
}
fibctx->jiffies = jiffies/HZ;
return status;
}
......@@ -405,10 +405,20 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
static int check_revision(struct aac_dev *dev, void __user *arg)
{
struct revision response;
response.compat = 1;
response.version = le32_to_cpu(dev->adapter_info.kernelrev);
response.build = le32_to_cpu(dev->adapter_info.kernelbuild);
char *driver_version = aac_driver_version;
u32 version;
response.compat = cpu_to_le32(1);
version = (simple_strtol(driver_version,
&driver_version, 10) << 24) | 0x00000400;
version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
version += simple_strtol(driver_version + 1, NULL, 10);
response.version = cpu_to_le32(version);
# if (defined(AAC_DRIVER_BUILD))
response.build = cpu_to_le32(AAC_DRIVER_BUILD);
# else
response.build = cpu_to_le32(9999);
# endif
if (copy_to_user(arg, &response, sizeof(response)))
return -EFAULT;
......
......@@ -44,7 +44,9 @@
#include "aacraid.h"
struct aac_common aac_config;
struct aac_common aac_config = {
.irq_mod = 1
};
static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
{
......
......@@ -254,6 +254,7 @@ static void fib_dealloc(struct fib * fibptr)
static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify)
{
struct aac_queue * q;
unsigned long idx;
/*
* All of the queues wrap when they reach the end, so we check
......@@ -263,10 +264,23 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
*/
q = &dev->queues->queue[qid];
*index = le32_to_cpu(*(q->headers.producer));
if ((*index - 2) == le32_to_cpu(*(q->headers.consumer)))
idx = *index = le32_to_cpu(*(q->headers.producer));
/* Interrupt Moderation, only interrupt for first two entries */
if (idx != le32_to_cpu(*(q->headers.consumer))) {
if (--idx == 0) {
if (qid == AdapHighCmdQueue)
idx = ADAP_HIGH_CMD_ENTRIES;
else if (qid == AdapNormCmdQueue)
idx = ADAP_NORM_CMD_ENTRIES;
else if (qid == AdapHighRespQueue)
idx = ADAP_HIGH_RESP_ENTRIES;
else if (qid == AdapNormRespQueue)
idx = ADAP_NORM_RESP_ENTRIES;
}
if (idx != le32_to_cpu(*(q->headers.consumer)))
*nonotify = 1;
}
if (qid == AdapHighCmdQueue) {
if (*index >= ADAP_HIGH_CMD_ENTRIES)
......
......@@ -27,8 +27,11 @@
* Abstract: Linux Driver entry module for Adaptec RAID Array Controller
*/
#define AAC_DRIVER_VERSION "1.1.2-lk2"
#define AAC_DRIVER_BUILD_DATE __DATE__
#define AAC_DRIVER_VERSION "1.1-4"
#ifndef AAC_DRIVER_BRANCH
#define AAC_DRIVER_BRANCH ""
#endif
#define AAC_DRIVER_BUILD_DATE __DATE__ " " __TIME__
#define AAC_DRIVERNAME "aacraid"
#include <linux/compat.h>
......@@ -58,16 +61,24 @@
#include "aacraid.h"
#ifdef AAC_DRIVER_BUILD
#define _str(x) #x
#define str(x) _str(x)
#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
#else
#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH " " AAC_DRIVER_BUILD_DATE
#endif
MODULE_AUTHOR("Red Hat Inc and Adaptec");
MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
"Adaptec Advanced Raid Products, "
"and HP NetRAID-4M SCSI driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(AAC_DRIVER_VERSION);
MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
static LIST_HEAD(aac_devices);
static int aac_cfg_major = -1;
char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
/*
* Because of the way Linux names scsi devices, the order in this table has
......@@ -109,36 +120,39 @@ static struct pci_device_id aac_pci_tbl[] = {
{ 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
{ 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
{ 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
{ 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 32 }, /* Themisto Jupiter Platform */
{ 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 32 }, /* Themisto Jupiter Platform */
{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 33 }, /* Callisto Jupiter Platform */
{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 34 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 35 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 36 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 37 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 38 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 39 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 40 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
{ 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 41 }, /* AAR-2610SA PCI SATA 6ch */
{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 42 }, /* ASR-2240S (SabreExpress) */
{ 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 43 }, /* ASR-4005SAS */
{ 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 44 }, /* IBM 8i (AvonPark) */
{ 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 44 }, /* IBM 8i (AvonPark Lite) */
{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 45 }, /* ASR-4000SAS (BlackBird) */
{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 46 }, /* ASR-4800SAS (Marauder-X) */
{ 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 47 }, /* ASR-4805SAS (Marauder-E) */
{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 48 }, /* ASR-4810SAS (Hurricane */
{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 49 }, /* Perc 320/DC*/
{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 50 }, /* Adaptec 5400S (Mustang)*/
{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 51 }, /* Adaptec 5400S (Mustang)*/
{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 52 }, /* Dell PERC2/QC */
{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 53 }, /* HP NetRAID-4M */
{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 54 }, /* Dell Catchall */
{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 55 }, /* Legend Catchall */
{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 56 }, /* Adaptec Catch All */
{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 57 }, /* Adaptec Rocket Catch All */
{ 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
{ 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 }, /* Themisto Jupiter Platform */
{ 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 }, /* Themisto Jupiter Platform */
{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 }, /* Callisto Jupiter Platform */
{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
{ 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */
{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */
{ 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005SAS */
{ 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */
{ 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */
{ 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */
{ 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */
{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000SAS (BlackBird) */
{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
{ 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-4810SAS (Hurricane */
{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 }, /* Adaptec 5400S (Mustang)*/
{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 }, /* Dell PERC2/QC */
{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 }, /* HP NetRAID-4M */
{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 57 }, /* Dell Catchall */
{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
{ 0,}
};
MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
......@@ -180,8 +194,9 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rkt_init, "aacraid", "ICP ", "ICP9047MA ", 1 }, /* ICP9047MA (Lancer) */
{ aac_rkt_init, "aacraid", "ICP ", "ICP9087MA ", 1 }, /* ICP9087MA (Lancer) */
{ aac_rkt_init, "aacraid", "ICP ", "ICP5085AU ", 1 }, /* ICP5085AU (Hurricane) */
{ aac_rkt_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */
{ aac_rkt_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */
{ aac_rx_init, "aacraid", "ICP ", "ICP9085LI ", 1 }, /* ICP9085LI (Marauder-X) */
{ aac_rx_init, "aacraid", "ICP ", "ICP5085BR ", 1 }, /* ICP5085BR (Marauder-E) */
{ aac_rkt_init, "aacraid", "ICP ", "ICP9067MA ", 1 }, /* ICP9067MA (Intruder-6) */
{ NULL , "aacraid", "ADAPTEC ", "Themisto ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */
{ aac_rkt_init, "aacraid", "ADAPTEC ", "Callisto ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020SA ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
......@@ -195,10 +210,12 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2240S ", 1 }, /* ASR-2240S (SabreExpress) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4005SAS ", 1 }, /* ASR-4005SAS */
{ aac_rx_init, "ServeRAID","IBM ", "ServeRAID 8i ", 1 }, /* IBM 8i (AvonPark) */
{ aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */
{ aac_rkt_init, "ServeRAID","IBM ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4000SAS ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4800SAS ", 1 }, /* ASR-4800SAS (Marauder-X) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4805SAS ", 1 }, /* ASR-4805SAS (Marauder-E) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */
{ aac_rkt_init, "aacraid", "ADAPTEC ", "ASR-4810SAS ", 1 }, /* ASR-4810SAS (Hurricane) */
{ aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
{ aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
......@@ -839,11 +856,12 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
return 0;
out_deinit:
out_deinit:
kill_proc(aac->thread_pid, SIGKILL, 0);
wait_for_completion(&aac->aif_completion);
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
fib_map_free(aac);
pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
kfree(aac->queues);
......@@ -860,6 +878,13 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
return error;
}
static void aac_shutdown(struct pci_dev *dev)
{
struct Scsi_Host *shost = pci_get_drvdata(dev);
struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
aac_send_shutdown(aac);
}
static void __devexit aac_remove_one(struct pci_dev *pdev)
{
struct Scsi_Host *shost = pci_get_drvdata(pdev);
......@@ -871,6 +896,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
wait_for_completion(&aac->aif_completion);
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
fib_map_free(aac);
pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
aac->comm_phys);
......@@ -891,14 +917,15 @@ static struct pci_driver aac_pci_driver = {
.id_table = aac_pci_tbl,
.probe = aac_probe_one,
.remove = __devexit_p(aac_remove_one),
.shutdown = aac_shutdown,
};
static int __init aac_init(void)
{
int error;
printk(KERN_INFO "Red Hat/Adaptec aacraid driver (%s %s)\n",
AAC_DRIVER_VERSION, AAC_DRIVER_BUILD_DATE);
printk(KERN_INFO "Adaptec %s driver (%s)\n",
AAC_DRIVERNAME, aac_driver_version);
error = pci_module_init(&aac_pci_driver);
if (error)
......@@ -909,6 +936,7 @@ static int __init aac_init(void)
printk(KERN_WARNING
"aacraid: unable to register \"aac\" device.\n");
}
return 0;
}
......
......@@ -87,6 +87,16 @@ static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
/**
* aac_rkt_disable_interrupt - Disable interrupts
* @dev: Adapter
*/
static void aac_rkt_disable_interrupt(struct aac_dev *dev)
{
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
}
/**
* rkt_sync_cmd - send a command and wait
* @dev: Adapter
......@@ -412,10 +422,19 @@ int aac_rkt_init(struct aac_dev *dev)
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt;
dev->a_ops.adapter_notify = aac_rkt_notify_adapter;
dev->a_ops.adapter_sync_cmd = rkt_sync_cmd;
dev->a_ops.adapter_check_health = aac_rkt_check_health;
/*
* First clear out all interrupts. Then enable the one's that we
* can handle.
*/
rkt_writeb(dev, MUnit.OIMR, 0xff);
rkt_writel(dev, MUnit.ODR, 0xffffffff);
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
if (aac_init_adapter(dev) == NULL)
goto error_irq;
/*
......@@ -438,6 +457,7 @@ int aac_rkt_init(struct aac_dev *dev)
kfree(dev->queues);
error_irq:
rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
......
......@@ -87,6 +87,16 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
/**
* aac_rx_disable_interrupt - Disable interrupts
* @dev: Adapter
*/
static void aac_rx_disable_interrupt(struct aac_dev *dev)
{
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
}
/**
* rx_sync_cmd - send a command and wait
* @dev: Adapter
......@@ -412,10 +422,19 @@ int aac_rx_init(struct aac_dev *dev)
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
dev->a_ops.adapter_notify = aac_rx_notify_adapter;
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_check_health = aac_rx_check_health;
/*
* First clear out all interrupts. Then enable the one's that we
* can handle.
*/
rx_writeb(dev, MUnit.OIMR, 0xff);
rx_writel(dev, MUnit.ODR, 0xffffffff);
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
if (aac_init_adapter(dev) == NULL)
goto error_irq;
/*
......@@ -438,6 +457,7 @@ int aac_rx_init(struct aac_dev *dev)
kfree(dev->queues);
error_irq:
rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
......
......@@ -81,6 +81,16 @@ static irqreturn_t aac_sa_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
/**
* aac_sa_disable_interrupt - disable interrupt
* @dev: Which adapter to enable.
*/
static void aac_sa_disable_interrupt (struct aac_dev *dev)
{
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
}
/**
* aac_sa_notify_adapter - handle adapter notification
* @dev: Adapter that notification is for
......@@ -214,9 +224,8 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
static void aac_sa_interrupt_adapter (struct aac_dev *dev)
{
u32 ret;
sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
&ret, NULL, NULL, NULL, NULL);
NULL, NULL, NULL, NULL, NULL);
}
/**
......@@ -352,10 +361,18 @@ int aac_sa_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
dev->a_ops.adapter_check_health = aac_sa_check_health;
/*
* First clear out all interrupts. Then enable the one's that
* we can handle.
*/
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
if(aac_init_adapter(dev) == NULL)
goto error_irq;
......@@ -381,6 +398,7 @@ int aac_sa_init(struct aac_dev *dev)
kfree(dev->queues);
error_irq:
sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
......
......@@ -9200,8 +9200,8 @@ asc_prt_scsi_cmnd(struct scsi_cmnd *s)
(unsigned) s->serial_number, s->retries, s->allowed);
printk(
" timeout_per_command %d, timeout_total %d, timeout %d\n",
s->timeout_per_command, s->timeout_total, s->timeout);
" timeout_per_command %d\n",
s->timeout_per_command);
printk(
" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
......
......@@ -5,6 +5,7 @@
config SCSI_AIC79XX
tristate "Adaptec AIC79xx U320 support"
depends on PCI && SCSI
select SCSI_SPI_ATTRS
help
This driver supports all of Adaptec's Ultra 320 PCI-X
based SCSI controllers.
......
......@@ -126,7 +126,6 @@ aic7770_find_device(uint32_t id)
int
aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
{
u_long l;
int error;
int have_seeprom;
u_int hostconf;
......
......@@ -1247,9 +1247,6 @@ struct ahd_softc {
uint16_t user_tagenable;/* Tagged Queuing allowed */
};
TAILQ_HEAD(ahd_softc_tailq, ahd_softc);
extern struct ahd_softc_tailq ahd_tailq;
/*************************** IO Cell Configuration ****************************/
#define AHD_PRECOMP_SLEW_INDEX \
(AHD_ANNEXCOL_PRECOMP_SLEW - AHD_ANNEXCOL_PER_DEV0)
......@@ -1374,8 +1371,6 @@ void ahd_enable_coalescing(struct ahd_softc *ahd,
void ahd_pause_and_flushwork(struct ahd_softc *ahd);
int ahd_suspend(struct ahd_softc *ahd);
int ahd_resume(struct ahd_softc *ahd);
void ahd_softc_insert(struct ahd_softc *);
struct ahd_softc *ahd_find_softc(struct ahd_softc *ahd);
void ahd_set_unit(struct ahd_softc *, int);
void ahd_set_name(struct ahd_softc *, char *);
struct scb *ahd_get_scb(struct ahd_softc *ahd, u_int col_idx);
......@@ -1524,7 +1519,6 @@ void ahd_print_scb(struct scb *scb);
void ahd_print_devinfo(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo);
void ahd_dump_sglist(struct scb *scb);
void ahd_dump_all_cards_state(void);
void ahd_dump_card_state(struct ahd_softc *ahd);
int ahd_print_register(ahd_reg_parse_entry_t *table,
u_int num_entries,
......
......@@ -52,8 +52,6 @@
#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
#endif
/******************************** Globals *************************************/
struct ahd_softc_tailq ahd_tailq = TAILQ_HEAD_INITIALIZER(ahd_tailq);
/***************************** Lookup Tables **********************************/
char *ahd_chip_names[] =
......@@ -5179,74 +5177,6 @@ ahd_softc_init(struct ahd_softc *ahd)
return (0);
}
void
ahd_softc_insert(struct ahd_softc *ahd)
{
struct ahd_softc *list_ahd;
#if AHD_PCI_CONFIG > 0
/*
* Second Function PCI devices need to inherit some
* settings from function 0.
*/
if ((ahd->features & AHD_MULTI_FUNC) != 0) {
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
ahd_dev_softc_t list_pci;
ahd_dev_softc_t pci;
list_pci = list_ahd->dev_softc;
pci = ahd->dev_softc;
if (ahd_get_pci_slot(list_pci) == ahd_get_pci_slot(pci)
&& ahd_get_pci_bus(list_pci) == ahd_get_pci_bus(pci)) {
struct ahd_softc *master;
struct ahd_softc *slave;
if (ahd_get_pci_function(list_pci) == 0) {
master = list_ahd;
slave = ahd;
} else {
master = ahd;
slave = list_ahd;
}
slave->flags &= ~AHD_BIOS_ENABLED;
slave->flags |=
master->flags & AHD_BIOS_ENABLED;
break;
}
}
}
#endif
/*
* Insertion sort into our list of softcs.
*/
list_ahd = TAILQ_FIRST(&ahd_tailq);
while (list_ahd != NULL
&& ahd_softc_comp(ahd, list_ahd) <= 0)
list_ahd = TAILQ_NEXT(list_ahd, links);
if (list_ahd != NULL)
TAILQ_INSERT_BEFORE(list_ahd, ahd, links);
else
TAILQ_INSERT_TAIL(&ahd_tailq, ahd, links);
ahd->init_level++;
}
/*
* Verify that the passed in softc pointer is for a
* controller that is still configured.
*/
struct ahd_softc *
ahd_find_softc(struct ahd_softc *ahd)
{
struct ahd_softc *list_ahd;
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
if (list_ahd == ahd)
return (ahd);
}
return (NULL);
}
void
ahd_set_unit(struct ahd_softc *ahd, int unit)
{
......@@ -7902,18 +7832,10 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset)
static void
ahd_reset_poll(void *arg)
{
struct ahd_softc *ahd;
struct ahd_softc *ahd = arg;
u_int scsiseq1;
u_long l;
u_long s;
ahd_list_lock(&l);
ahd = ahd_find_softc((struct ahd_softc *)arg);
if (ahd == NULL) {
printf("ahd_reset_poll: Instance %p no longer exists\n", arg);
ahd_list_unlock(&l);
return;
}
ahd_lock(ahd, &s);
ahd_pause(ahd);
ahd_update_modes(ahd);
......@@ -7924,7 +7846,6 @@ ahd_reset_poll(void *arg)
ahd_reset_poll, ahd);
ahd_unpause(ahd);
ahd_unlock(ahd, &s);
ahd_list_unlock(&l);
return;
}
......@@ -7936,25 +7857,16 @@ ahd_reset_poll(void *arg)
ahd->flags &= ~AHD_RESET_POLL_ACTIVE;
ahd_unlock(ahd, &s);
ahd_release_simq(ahd);
ahd_list_unlock(&l);
}
/**************************** Statistics Processing ***************************/
static void
ahd_stat_timer(void *arg)
{
struct ahd_softc *ahd;
u_long l;
struct ahd_softc *ahd = arg;
u_long s;
int enint_coal;
ahd_list_lock(&l);
ahd = ahd_find_softc((struct ahd_softc *)arg);
if (ahd == NULL) {
printf("ahd_stat_timer: Instance %p no longer exists\n", arg);
ahd_list_unlock(&l);
return;
}
ahd_lock(ahd, &s);
enint_coal = ahd->hs_mailbox & ENINT_COALESCE;
......@@ -7981,7 +7893,6 @@ ahd_stat_timer(void *arg)
ahd_timer_reset(&ahd->stat_timer, AHD_STAT_UPDATE_US,
ahd_stat_timer, ahd);
ahd_unlock(ahd, &s);
ahd_list_unlock(&l);
}
/****************************** Status Processing *****************************/
......@@ -8745,16 +8656,6 @@ ahd_probe_stack_size(struct ahd_softc *ahd)
return (last_probe);
}
void
ahd_dump_all_cards_state(void)
{
struct ahd_softc *list_ahd;
TAILQ_FOREACH(list_ahd, &ahd_tailq, links) {
ahd_dump_card_state(list_ahd);
}
}
int
ahd_print_register(ahd_reg_parse_entry_t *table, u_int num_entries,
const char *name, u_int address, u_int value,
......@@ -9039,7 +8940,6 @@ ahd_dump_card_state(struct ahd_softc *ahd)
ahd_outb(ahd, STACK, (ahd->saved_stack[i] >> 8) & 0xFF);
}
printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n");
ahd_platform_dump_card_state(ahd);
ahd_restore_modes(ahd, saved_modes);
if (paused == 0)
ahd_unpause(ahd);
......
此差异已折叠。
......@@ -42,6 +42,7 @@
#ifndef _AIC79XX_LINUX_H_
#define _AIC79XX_LINUX_H_
#include <linux/config.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
......@@ -49,18 +50,23 @@
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <linux/interrupt.h> /* For tasklet support. */
#include <linux/config.h>
#include <linux/slab.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_spi.h>
/* Core SCSI definitions */
#define AIC_LIB_PREFIX ahd
#include "scsi.h"
#include <scsi/scsi_host.h>
/* Name space conflict with BSD queue macros */
#ifdef LIST_HEAD
......@@ -95,7 +101,7 @@
/************************* Forward Declarations *******************************/
struct ahd_softc;
typedef struct pci_dev *ahd_dev_softc_t;
typedef Scsi_Cmnd *ahd_io_ctx_t;
typedef struct scsi_cmnd *ahd_io_ctx_t;
/******************************* Byte Order ***********************************/
#define ahd_htobe16(x) cpu_to_be16(x)
......@@ -114,8 +120,7 @@ typedef Scsi_Cmnd *ahd_io_ctx_t;
/************************* Configuration Data *********************************/
extern uint32_t aic79xx_allow_memio;
extern int aic79xx_detect_complete;
extern Scsi_Host_Template aic79xx_driver_template;
extern struct scsi_host_template aic79xx_driver_template;
/***************************** Bus Space/DMA **********************************/
......@@ -145,11 +150,7 @@ struct ahd_linux_dma_tag
};
typedef struct ahd_linux_dma_tag* bus_dma_tag_t;
struct ahd_linux_dmamap
{
dma_addr_t bus_addr;
};
typedef struct ahd_linux_dmamap* bus_dmamap_t;
typedef dma_addr_t bus_dmamap_t;
typedef int bus_dma_filter_t(void*, dma_addr_t);
typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
......@@ -226,12 +227,12 @@ typedef struct timer_list ahd_timer_t;
#define ahd_timer_init init_timer
#define ahd_timer_stop del_timer_sync
typedef void ahd_linux_callback_t (u_long);
static __inline void ahd_timer_reset(ahd_timer_t *timer, u_int usec,
static __inline void ahd_timer_reset(ahd_timer_t *timer, int usec,
ahd_callback_t *func, void *arg);
static __inline void ahd_scb_timer_reset(struct scb *scb, u_int usec);
static __inline void
ahd_timer_reset(ahd_timer_t *timer, u_int usec, ahd_callback_t *func, void *arg)
ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg)
{
struct ahd_softc *ahd;
......@@ -252,43 +253,8 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
/***************************** SMP support ************************************/
#include <linux/spinlock.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
#define AHD_SCSI_HAS_HOST_LOCK 1
#else
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.11"
/**************************** Front End Queues ********************************/
/*
* Data structure used to cast the Linux struct scsi_cmnd to something
* that allows us to use the queue macros. The linux structure has
* plenty of space to hold the links fields as required by the queue
* macros, but the queue macors require them to have the correct type.
*/
struct ahd_cmd_internal {
/* Area owned by the Linux scsi layer. */
uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
union {
STAILQ_ENTRY(ahd_cmd) ste;
LIST_ENTRY(ahd_cmd) le;
TAILQ_ENTRY(ahd_cmd) tqe;
} links;
uint32_t end;
};
struct ahd_cmd {
union {
struct ahd_cmd_internal icmd;
struct scsi_cmnd scsi_cmd;
} un;
};
#define acmd_icmd(cmd) ((cmd)->un.icmd)
#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
#define acmd_links un.icmd.links
/*************************** Device Data Structures ***************************/
/*
* A per probed device structure used to deal with some error recovery
......@@ -297,22 +263,17 @@ struct ahd_cmd {
* after a successfully completed inquiry command to the target when
* that inquiry data indicates a lun is present.
*/
TAILQ_HEAD(ahd_busyq, ahd_cmd);
typedef enum {
AHD_DEV_UNCONFIGURED = 0x01,
AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
AHD_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */
AHD_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */
AHD_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */
AHD_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */
AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */
AHD_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */
} ahd_linux_dev_flags;
struct ahd_linux_target;
struct ahd_linux_device {
TAILQ_ENTRY(ahd_linux_device) links;
struct ahd_busyq busyq;
/*
* The number of transactions currently
......@@ -388,62 +349,12 @@ struct ahd_linux_device {
*/
u_int commands_since_idle_or_otag;
#define AHD_OTAG_THRESH 500
int lun;
Scsi_Device *scsi_device;
struct ahd_linux_target *target;
};
typedef enum {
AHD_DV_REQUIRED = 0x01,
AHD_INQ_VALID = 0x02,
AHD_BASIC_DV = 0x04,
AHD_ENHANCED_DV = 0x08
} ahd_linux_targ_flags;
/* DV States */
typedef enum {
AHD_DV_STATE_EXIT = 0,
AHD_DV_STATE_INQ_SHORT_ASYNC,
AHD_DV_STATE_INQ_ASYNC,
AHD_DV_STATE_INQ_ASYNC_VERIFY,
AHD_DV_STATE_TUR,
AHD_DV_STATE_REBD,
AHD_DV_STATE_INQ_VERIFY,
AHD_DV_STATE_WEB,
AHD_DV_STATE_REB,
AHD_DV_STATE_SU,
AHD_DV_STATE_BUSY
} ahd_dv_state;
struct ahd_linux_target {
struct ahd_linux_device *devices[AHD_NUM_LUNS];
int channel;
int target;
int refcount;
struct scsi_device *sdev[AHD_NUM_LUNS];
struct ahd_transinfo last_tinfo;
struct ahd_softc *ahd;
ahd_linux_targ_flags flags;
struct scsi_inquiry_data *inq_data;
/*
* The next "fallback" period to use for narrow/wide transfers.
*/
uint8_t dv_next_narrow_period;
uint8_t dv_next_wide_period;
uint8_t dv_max_width;
uint8_t dv_max_ppr_options;
uint8_t dv_last_ppr_options;
u_int dv_echo_size;
ahd_dv_state dv_state;
u_int dv_state_retry;
uint8_t *dv_buffer;
uint8_t *dv_buffer1;
/*
* Cumulative counter of errors.
*/
u_long errors_detected;
u_long cmds_since_error;
};
/********************* Definitions Required by the Core ***********************/
......@@ -453,32 +364,16 @@ struct ahd_linux_target {
* manner and are allocated below 4GB, the number of S/G segments is
* unrestricted.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* We dynamically adjust the number of segments in pre-2.5 kernels to
* avoid fragmentation issues in the SCSI mid-layer's private memory
* allocator. See aic79xx_osm.c ahd_linux_size_nseg() for details.
*/
extern u_int ahd_linux_nseg;
#define AHD_NSEG ahd_linux_nseg
#define AHD_LINUX_MIN_NSEG 64
#else
#define AHD_NSEG 128
#endif
/*
* Per-SCB OSM storage.
*/
typedef enum {
AHD_SCB_UP_EH_SEM = 0x1
} ahd_linux_scb_flags;
struct scb_platform_data {
struct ahd_linux_device *dev;
dma_addr_t buf_busaddr;
uint32_t xfer_len;
uint32_t sense_resid; /* Auto-Sense residual */
ahd_linux_scb_flags flags;
};
/*
......@@ -487,44 +382,23 @@ struct scb_platform_data {
* alignment restrictions of the various platforms supported by
* this driver.
*/
typedef enum {
AHD_DV_WAIT_SIMQ_EMPTY = 0x01,
AHD_DV_WAIT_SIMQ_RELEASE = 0x02,
AHD_DV_ACTIVE = 0x04,
AHD_DV_SHUTDOWN = 0x08,
AHD_RUN_CMPLT_Q_TIMER = 0x10
} ahd_linux_softc_flags;
TAILQ_HEAD(ahd_completeq, ahd_cmd);
struct ahd_platform_data {
/*
* Fields accessed from interrupt context.
*/
struct ahd_linux_target *targets[AHD_NUM_TARGETS];
TAILQ_HEAD(, ahd_linux_device) device_runq;
struct ahd_completeq completeq;
struct scsi_target *starget[AHD_NUM_TARGETS];
spinlock_t spin_lock;
struct tasklet_struct runq_tasklet;
u_int qfrozen;
pid_t dv_pid;
struct timer_list completeq_timer;
struct timer_list reset_timer;
struct timer_list stats_timer;
struct semaphore eh_sem;
struct semaphore dv_sem;
struct semaphore dv_cmd_sem; /* XXX This needs to be in
* the target struct
*/
struct scsi_device *dv_scsi_dev;
struct Scsi_Host *host; /* pointer to scsi host */
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */
uint32_t bios_address;
uint32_t mem_busaddr; /* Mem Base Addr */
uint64_t hw_dma_mask;
ahd_linux_softc_flags flags;
#define AHD_SCB_UP_EH_SEM 0x1
uint32_t flags;
};
/************************** OS Utility Wrappers *******************************/
......@@ -641,7 +515,7 @@ ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
/**************************** Initialization **********************************/
int ahd_linux_register_host(struct ahd_softc *,
Scsi_Host_Template *);
struct scsi_host_template *);
uint64_t ahd_linux_get_memsize(void);
......@@ -657,28 +531,6 @@ void ahd_format_transinfo(struct info_str *info,
struct ahd_transinfo *tinfo);
/******************************** Locking *************************************/
/* Lock protecting internal data structures */
static __inline void ahd_lockinit(struct ahd_softc *);
static __inline void ahd_lock(struct ahd_softc *, unsigned long *flags);
static __inline void ahd_unlock(struct ahd_softc *, unsigned long *flags);
/* Lock acquisition and release of the above lock in midlayer entry points. */
static __inline void ahd_midlayer_entrypoint_lock(struct ahd_softc *,
unsigned long *flags);
static __inline void ahd_midlayer_entrypoint_unlock(struct ahd_softc *,
unsigned long *flags);
/* Lock held during command compeletion to the upper layer */
static __inline void ahd_done_lockinit(struct ahd_softc *);
static __inline void ahd_done_lock(struct ahd_softc *, unsigned long *flags);
static __inline void ahd_done_unlock(struct ahd_softc *, unsigned long *flags);
/* Lock held during ahd_list manipulation and ahd softc frees */
extern spinlock_t ahd_list_spinlock;
static __inline void ahd_list_lockinit(void);
static __inline void ahd_list_lock(unsigned long *flags);
static __inline void ahd_list_unlock(unsigned long *flags);
static __inline void
ahd_lockinit(struct ahd_softc *ahd)
{
......@@ -697,75 +549,6 @@ ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
}
static __inline void
ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* In 2.5.X and some 2.4.X versions, the midlayer takes our
* lock just before calling us, so we avoid locking again.
* For other kernel versions, the io_request_lock is taken
* just before our entry point is called. In this case, we
* trade the io_request_lock for our per-softc lock.
*/
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
spin_lock(&ahd->platform_data->spin_lock);
#endif
}
static __inline void
ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&ahd->platform_data->spin_lock);
spin_lock(&io_request_lock);
#endif
}
static __inline void
ahd_done_lockinit(struct ahd_softc *ahd)
{
/*
* In 2.5.X, our own lock is held during completions.
* In previous versions, the io_request_lock is used.
* In either case, we can't initialize this lock again.
*/
}
static __inline void
ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
{
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_lock(&io_request_lock);
#endif
}
static __inline void
ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
#endif
}
static __inline void
ahd_list_lockinit(void)
{
spin_lock_init(&ahd_list_spinlock);
}
static __inline void
ahd_list_lock(unsigned long *flags)
{
spin_lock_irqsave(&ahd_list_spinlock, *flags);
}
static __inline void
ahd_list_unlock(unsigned long *flags)
{
spin_unlock_irqrestore(&ahd_list_spinlock, *flags);
}
/******************************* PCI Definitions ******************************/
/*
* PCIM_xxx: mask to locate subfield in register
......@@ -925,27 +708,17 @@ ahd_flush_device_writes(struct ahd_softc *ahd)
}
/**************************** Proc FS Support *********************************/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
int ahd_linux_proc_info(char *, char **, off_t, int, int, int);
#else
int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
off_t, int, int);
#endif
/*************************** Domain Validation ********************************/
#define AHD_DV_CMD(cmd) ((cmd)->scsi_done == ahd_linux_dv_complete)
#define AHD_DV_SIMQ_FROZEN(ahd) \
((((ahd)->platform_data->flags & AHD_DV_ACTIVE) != 0) \
&& (ahd)->platform_data->qfrozen == 1)
/*********************** Transaction Access Wrappers **************************/
static __inline void ahd_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
static __inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
static __inline void ahd_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
static __inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
static __inline uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd);
static __inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
static __inline uint32_t ahd_get_transaction_status(struct scb *);
static __inline uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd);
static __inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
static __inline uint32_t ahd_get_scsi_status(struct scb *);
static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
static __inline u_long ahd_get_transfer_length(struct scb *);
......@@ -964,7 +737,7 @@ static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
static __inline void ahd_freeze_scb(struct scb *scb);
static __inline
void ahd_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
......@@ -977,7 +750,7 @@ void ahd_set_transaction_status(struct scb *scb, uint32_t status)
}
static __inline
void ahd_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~0xFFFF;
cmd->result |= status;
......@@ -990,7 +763,7 @@ void ahd_set_scsi_status(struct scb *scb, uint32_t status)
}
static __inline
uint32_t ahd_cmd_get_transaction_status(Scsi_Cmnd *cmd)
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
......@@ -1002,7 +775,7 @@ uint32_t ahd_get_transaction_status(struct scb *scb)
}
static __inline
uint32_t ahd_cmd_get_scsi_status(Scsi_Cmnd *cmd)
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
return (cmd->result & 0xFFFF);
}
......@@ -1117,7 +890,6 @@ void ahd_done(struct ahd_softc*, struct scb*);
void ahd_send_async(struct ahd_softc *, char channel,
u_int target, u_int lun, ac_code, void *);
void ahd_print_path(struct ahd_softc *, struct scb *);
void ahd_platform_dump_card_state(struct ahd_softc *ahd);
#ifdef CONFIG_PCI
#define AHD_PCI_CONFIG 1
......
......@@ -92,27 +92,31 @@ struct pci_driver aic79xx_pci_driver = {
static void
ahd_linux_pci_dev_remove(struct pci_dev *pdev)
{
struct ahd_softc *ahd;
u_long l;
struct ahd_softc *ahd = pci_get_drvdata(pdev);
u_long s;
/*
* We should be able to just perform
* the free directly, but check our
* list for extra sanity.
*/
ahd_list_lock(&l);
ahd = ahd_find_softc((struct ahd_softc *)pci_get_drvdata(pdev));
if (ahd != NULL) {
u_long s;
TAILQ_REMOVE(&ahd_tailq, ahd, links);
ahd_list_unlock(&l);
ahd_lock(ahd, &s);
ahd_intr_enable(ahd, FALSE);
ahd_unlock(ahd, &s);
ahd_free(ahd);
} else
ahd_list_unlock(&l);
ahd_lock(ahd, &s);
ahd_intr_enable(ahd, FALSE);
ahd_unlock(ahd, &s);
ahd_free(ahd);
}
static void
ahd_linux_pci_inherit_flags(struct ahd_softc *ahd)
{
struct pci_dev *pdev = ahd->dev_softc, *master_pdev;
unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
master_pdev = pci_get_slot(pdev->bus, master_devfn);
if (master_pdev) {
struct ahd_softc *master = pci_get_drvdata(master_pdev);
if (master) {
ahd->flags &= ~AHD_BIOS_ENABLED;
ahd->flags |= master->flags & AHD_BIOS_ENABLED;
} else
printk(KERN_ERR "aic79xx: no multichannel peer found!\n");
pci_dev_put(master_pdev);
}
}
static int
......@@ -125,22 +129,6 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
char *name;
int error;
/*
* Some BIOSen report the same device multiple times.
*/
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
struct pci_dev *probed_pdev;
probed_pdev = ahd->dev_softc;
if (probed_pdev->bus->number == pdev->bus->number
&& probed_pdev->devfn == pdev->devfn)
break;
}
if (ahd != NULL) {
/* Skip duplicate. */
return (-ENODEV);
}
pci = pdev;
entry = ahd_find_pci_device(pci);
if (entry == NULL)
......@@ -177,15 +165,12 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (memsize >= 0x8000000000ULL
&& pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
ahd->flags |= AHD_64BIT_ADDRESSING;
ahd->platform_data->hw_dma_mask = DMA_64BIT_MASK;
} else if (memsize > 0x80000000
&& pci_set_dma_mask(pdev, mask_39bit) == 0) {
ahd->flags |= AHD_39BIT_ADDRESSING;
ahd->platform_data->hw_dma_mask = mask_39bit;
}
} else {
pci_set_dma_mask(pdev, DMA_32BIT_MASK);
ahd->platform_data->hw_dma_mask = DMA_32BIT_MASK;
}
ahd->dev_softc = pci;
error = ahd_pci_config(ahd, entry);
......@@ -193,16 +178,17 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ahd_free(ahd);
return (-error);
}
/*
* Second Function PCI devices need to inherit some
* * settings from function 0.
*/
if ((ahd->features & AHD_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0)
ahd_linux_pci_inherit_flags(ahd);
pci_set_drvdata(pdev, ahd);
if (aic79xx_detect_complete) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahd_linux_register_host(ahd, &aic79xx_driver_template);
#else
printf("aic79xx: ignoring PCI device found after "
"initialization\n");
return (-ENODEV);
#endif
}
ahd_linux_register_host(ahd, &aic79xx_driver_template);
return (0);
}
......
......@@ -283,7 +283,6 @@ int
ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
{
struct scb_data *shared_scb_data;
u_long l;
u_int command;
uint32_t devconfig;
uint16_t subvendor;
......@@ -373,16 +372,9 @@ ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
* Allow interrupts now that we are completely setup.
*/
error = ahd_pci_map_int(ahd);
if (error != 0)
return (error);
ahd_list_lock(&l);
/*
* Link this softc in with all other ahd instances.
*/
ahd_softc_insert(ahd);
ahd_list_unlock(&l);
return (0);
if (!error)
ahd->init_level++;
return error;
}
/*
......
此差异已折叠。
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#79 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#85 $
*
* $FreeBSD$
*/
......@@ -243,7 +243,7 @@ typedef enum {
*/
AHC_AIC7850_FE = AHC_SPIOCAP|AHC_AUTOPAUSE|AHC_TARGETMODE|AHC_ULTRA,
AHC_AIC7860_FE = AHC_AIC7850_FE,
AHC_AIC7870_FE = AHC_TARGETMODE,
AHC_AIC7870_FE = AHC_TARGETMODE|AHC_AUTOPAUSE,
AHC_AIC7880_FE = AHC_AIC7870_FE|AHC_ULTRA,
/*
* Although we have space for both the initiator and
......
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#39 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -1306,7 +1306,6 @@ scratch_ram {
*/
MWI_RESIDUAL {
size 1
alias TARG_IMMEDIATE_SCB
}
/*
* SCBID of the next SCB to be started by the controller.
......@@ -1461,6 +1460,7 @@ scratch_ram {
*/
LAST_MSG {
size 1
alias TARG_IMMEDIATE_SCB
}
/*
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#56 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $"
PATCH_ARG_LIST = "struct ahc_softc *ahc"
PREFIX = "ahc_"
......@@ -679,6 +679,7 @@ await_busfree:
clr SCSIBUSL; /* Prevent bit leakage durint SELTO */
}
and SXFRCTL0, ~SPIOEN;
mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT;
test SSTAT1,REQINIT|BUSFREE jz .;
test SSTAT1, BUSFREE jnz poll_for_work;
mvi MISSED_BUSFREE call set_seqint;
......@@ -1097,7 +1098,7 @@ ultra2_dmahalt:
test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz dma_mid_sg;
if ((ahc->flags & AHC_TARGETROLE) != 0) {
test SSTAT0, TARGET jz dma_last_sg;
if ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0) {
if ((ahc->bugs & AHC_TMODE_WIDEODD_BUG) != 0) {
test DMAPARAMS, DIRECTION jz dma_mid_sg;
}
}
......
......@@ -28,9 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#17 $
*
* $FreeBSD$
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#19 $
*/
/*
......@@ -64,7 +62,6 @@
* is preceded by an initial zero (leading 0, followed by 16-bits, MSB
* first). The clock cycling from low to high initiates the next data
* bit to be sent from the chip.
*
*/
#ifdef __linux__
......@@ -81,14 +78,22 @@
* Right now, we only have to read the SEEPROM. But we make it easier to
* add other 93Cx6 functions.
*/
static struct seeprom_cmd {
struct seeprom_cmd {
uint8_t len;
uint8_t bits[9];
} seeprom_read = {3, {1, 1, 0}};
uint8_t bits[11];
};
/* Short opcodes for the c46 */
static struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
static struct seeprom_cmd seeprom_ewds = {9, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
/* Long opcodes for the C56/C66 */
static struct seeprom_cmd seeprom_long_ewen = {11, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
static struct seeprom_cmd seeprom_long_ewds = {11, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
/* Common opcodes */
static struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
static struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
/*
* Wait for the SEERDY to go high; about 800 ns.
......@@ -222,12 +227,25 @@ int
ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
u_int start_addr, u_int count)
{
struct seeprom_cmd *ewen, *ewds;
uint16_t v;
uint8_t temp;
int i, k;
/* Place the chip into write-enable mode */
send_seeprom_cmd(sd, &seeprom_ewen);
if (sd->sd_chip == C46) {
ewen = &seeprom_ewen;
ewds = &seeprom_ewds;
} else if (sd->sd_chip == C56_66) {
ewen = &seeprom_long_ewen;
ewds = &seeprom_long_ewds;
} else {
printf("ahc_write_seeprom: unsupported seeprom type %d\n",
sd->sd_chip);
return (0);
}
send_seeprom_cmd(sd, ewen);
reset_seeprom(sd);
/* Write all requested data out to the seeprom. */
......@@ -277,7 +295,7 @@ ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
}
/* Put the chip back into write-protect mode */
send_seeprom_cmd(sd, &seeprom_ewds);
send_seeprom_cmd(sd, ewds);
reset_seeprom(sd);
return (1);
......
此差异已折叠。
此差异已折叠。
......@@ -265,7 +265,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec)
/***************************** SMP support ************************************/
#include <linux/spinlock.h>
#define AIC7XXX_DRIVER_VERSION "6.2.36"
#define AIC7XXX_DRIVER_VERSION "7.0"
/*************************** Device Data Structures ***************************/
/*
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部