提交 064922a8 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (40 commits)
  [SCSI] jazz_esp, sgiwd93, sni_53c710, sun3x_esp: fix platform driver hotplug/coldplug
  [SCSI] aic7xxx: add const
  [SCSI] aic7xxx: add static
  [SCSI] aic7xxx: Update _shipped files
  [SCSI] aic7xxx: teach aicasm to not emit unused debug code/data
  [SCSI] qla2xxx: Update version number to 8.02.01-k2.
  [SCSI] qla2xxx: Correct regression in relogin code.
  [SCSI] qla2xxx: Correct misc. endian and byte-ordering issues.
  [SCSI] qla2xxx: make qla2x00_issue_iocb_timeout() static
  [SCSI] qla2xxx: qla_os.c, make 2 functions static
  [SCSI] qla2xxx: Re-register FDMI information after a LIP.
  [SCSI] qla2xxx: Correct SRB usage-after-completion/free issues.
  [SCSI] qla2xxx: Correct ISP84XX verify-chip response handling.
  [SCSI] qla2xxx: Wakeup DPC thread to process any deferred-work requests.
  [SCSI] qla2xxx: Collapse RISC-RAM retrieval code during a firmware-dump.
  [SCSI] m68k: new mac_esp scsi driver
  [SCSI] zfcp: Add some statistics provided by the FCP adapter to the sysfs
  [SCSI] zfcp: Print some messages only during ERP
  [SCSI] zfcp: Wait for free SBAL during exchange config
  [SCSI] scsi_transport_fc: fc_user_scan correction
  ...
......@@ -699,14 +699,26 @@ static struct bsg_device *bsg_alloc_device(void)
return bd;
}
static void bsg_kref_release_function(struct kref *kref)
{
struct bsg_class_device *bcd =
container_of(kref, struct bsg_class_device, ref);
if (bcd->release)
bcd->release(bcd->parent);
put_device(bcd->parent);
}
static int bsg_put_device(struct bsg_device *bd)
{
int ret = 0;
struct device *dev = bd->queue->bsg_dev.dev;
int ret = 0, do_free;
struct request_queue *q = bd->queue;
mutex_lock(&bsg_mutex);
if (!atomic_dec_and_test(&bd->ref_count))
do_free = atomic_dec_and_test(&bd->ref_count);
if (!do_free)
goto out;
dprintk("%s: tearing down\n", bd->name);
......@@ -723,12 +735,13 @@ static int bsg_put_device(struct bsg_device *bd)
*/
ret = bsg_complete_all_commands(bd);
blk_put_queue(bd->queue);
hlist_del(&bd->dev_list);
kfree(bd);
out:
mutex_unlock(&bsg_mutex);
put_device(dev);
kref_put(&q->bsg_dev.ref, bsg_kref_release_function);
if (do_free)
blk_put_queue(q);
return ret;
}
......@@ -796,7 +809,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
mutex_lock(&bsg_mutex);
bcd = idr_find(&bsg_minor_idr, iminor(inode));
if (bcd)
get_device(bcd->dev);
kref_get(&bcd->ref);
mutex_unlock(&bsg_mutex);
if (!bcd)
......@@ -808,7 +821,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
bd = bsg_add_device(inode, bcd->queue, file);
if (IS_ERR(bd))
put_device(bcd->dev);
kref_put(&bcd->ref, bsg_kref_release_function);
return bd;
}
......@@ -947,14 +960,14 @@ void bsg_unregister_queue(struct request_queue *q)
idr_remove(&bsg_minor_idr, bcd->minor);
sysfs_remove_link(&q->kobj, "bsg");
device_unregister(bcd->class_dev);
put_device(bcd->dev);
bcd->class_dev = NULL;
kref_put(&bcd->ref, bsg_kref_release_function);
mutex_unlock(&bsg_mutex);
}
EXPORT_SYMBOL_GPL(bsg_unregister_queue);
int bsg_register_queue(struct request_queue *q, struct device *gdev,
const char *name)
int bsg_register_queue(struct request_queue *q, struct device *parent,
const char *name, void (*release)(struct device *))
{
struct bsg_class_device *bcd;
dev_t dev;
......@@ -965,7 +978,7 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,
if (name)
devname = name;
else
devname = gdev->bus_id;
devname = parent->bus_id;
/*
* we need a proper transport to send commands, not a stacked device
......@@ -996,9 +1009,11 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,
bcd->minor = minor;
bcd->queue = q;
bcd->dev = get_device(gdev);
bcd->parent = get_device(parent);
bcd->release = release;
kref_init(&bcd->ref);
dev = MKDEV(bsg_major, bcd->minor);
class_dev = device_create(bsg_class, gdev, dev, "%s", devname);
class_dev = device_create(bsg_class, parent, dev, "%s", devname);
if (IS_ERR(class_dev)) {
ret = PTR_ERR(class_dev);
goto put_dev;
......@@ -1017,7 +1032,7 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,
unregister_class_dev:
device_unregister(class_dev);
put_dev:
put_device(gdev);
put_device(parent);
remove_idr:
idr_remove(&bsg_minor_idr, minor);
unlock:
......
......@@ -31,7 +31,6 @@
static LIST_HEAD(container_list);
static DEFINE_MUTEX(container_list_lock);
static struct class enclosure_class;
static struct class enclosure_component_class;
/**
* enclosure_find - find an enclosure given a device
......@@ -166,6 +165,40 @@ void enclosure_unregister(struct enclosure_device *edev)
}
EXPORT_SYMBOL_GPL(enclosure_unregister);
#define ENCLOSURE_NAME_SIZE 64
static void enclosure_link_name(struct enclosure_component *cdev, char *name)
{
strcpy(name, "enclosure_device:");
strcat(name, cdev->cdev.bus_id);
}
static void enclosure_remove_links(struct enclosure_component *cdev)
{
char name[ENCLOSURE_NAME_SIZE];
enclosure_link_name(cdev, name);
sysfs_remove_link(&cdev->dev->kobj, name);
sysfs_remove_link(&cdev->cdev.kobj, "device");
}
static int enclosure_add_links(struct enclosure_component *cdev)
{
int error;
char name[ENCLOSURE_NAME_SIZE];
error = sysfs_create_link(&cdev->cdev.kobj, &cdev->dev->kobj, "device");
if (error)
return error;
enclosure_link_name(cdev, name);
error = sysfs_create_link(&cdev->dev->kobj, &cdev->cdev.kobj, name);
if (error)
sysfs_remove_link(&cdev->cdev.kobj, "device");
return error;
}
static void enclosure_release(struct device *cdev)
{
struct enclosure_device *edev = to_enclosure_device(cdev);
......@@ -178,10 +211,15 @@ static void enclosure_component_release(struct device *dev)
{
struct enclosure_component *cdev = to_enclosure_component(dev);
put_device(cdev->dev);
if (cdev->dev) {
enclosure_remove_links(cdev);
put_device(cdev->dev);
}
put_device(dev->parent);
}
static struct attribute_group *enclosure_groups[];
/**
* enclosure_component_register - add a particular component to an enclosure
* @edev: the enclosure to add the component
......@@ -217,12 +255,14 @@ enclosure_component_register(struct enclosure_device *edev,
ecomp->number = number;
cdev = &ecomp->cdev;
cdev->parent = get_device(&edev->edev);
cdev->class = &enclosure_component_class;
if (name)
snprintf(cdev->bus_id, BUS_ID_SIZE, "%s", name);
else
snprintf(cdev->bus_id, BUS_ID_SIZE, "%u", number);
cdev->release = enclosure_component_release;
cdev->groups = enclosure_groups;
err = device_register(cdev);
if (err)
ERR_PTR(err);
......@@ -255,10 +295,12 @@ int enclosure_add_device(struct enclosure_device *edev, int component,
cdev = &edev->component[component];
device_del(&cdev->cdev);
if (cdev->dev)
enclosure_remove_links(cdev);
put_device(cdev->dev);
cdev->dev = get_device(dev);
return device_add(&cdev->cdev);
return enclosure_add_links(cdev);
}
EXPORT_SYMBOL_GPL(enclosure_add_device);
......@@ -442,24 +484,32 @@ static ssize_t get_component_type(struct device *cdev,
}
static struct device_attribute enclosure_component_attrs[] = {
__ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
set_component_fault),
__ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
set_component_status),
__ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
set_component_active),
__ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
set_component_locate),
__ATTR(type, S_IRUGO, get_component_type, NULL),
__ATTR_NULL
static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
set_component_fault);
static DEVICE_ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
set_component_status);
static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
set_component_active);
static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
set_component_locate);
static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
static struct attribute *enclosure_component_attrs[] = {
&dev_attr_fault.attr,
&dev_attr_status.attr,
&dev_attr_active.attr,
&dev_attr_locate.attr,
&dev_attr_type.attr,
NULL
};
static struct class enclosure_component_class = {
.name = "enclosure_component",
.owner = THIS_MODULE,
.dev_attrs = enclosure_component_attrs,
.dev_release = enclosure_component_release,
static struct attribute_group enclosure_group = {
.attrs = enclosure_component_attrs,
};
static struct attribute_group *enclosure_groups[] = {
&enclosure_group,
NULL
};
static int __init enclosure_init(void)
......@@ -469,20 +519,12 @@ static int __init enclosure_init(void)
err = class_register(&enclosure_class);
if (err)
return err;
err = class_register(&enclosure_component_class);
if (err)
goto err_out;
return 0;
err_out:
class_unregister(&enclosure_class);
return err;
}
static void __exit enclosure_exit(void)
{
class_unregister(&enclosure_component_class);
class_unregister(&enclosure_class);
}
......
......@@ -1927,7 +1927,8 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
0, NULL, &lock_flags, &fsf_req);
ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags,
&fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n",
......@@ -2035,21 +2036,21 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
min(FC_SERIAL_NUMBER_SIZE, 17));
}
ZFCP_LOG_NORMAL("The adapter %s reported the following "
"characteristics:\n"
"WWNN 0x%016Lx, "
"WWPN 0x%016Lx, "
"S_ID 0x%06x,\n"
"adapter version 0x%x, "
"LIC version 0x%x, "
"FC link speed %d Gb/s\n",
zfcp_get_busid_by_adapter(adapter),
(wwn_t) fc_host_node_name(shost),
(wwn_t) fc_host_port_name(shost),
fc_host_port_id(shost),
adapter->hydra_version,
adapter->fsf_lic_version,
fc_host_speed(shost));
if (fsf_req->erp_action)
ZFCP_LOG_NORMAL("The adapter %s reported the following "
"characteristics:\n"
"WWNN 0x%016Lx, WWPN 0x%016Lx, "
"S_ID 0x%06x,\n"
"adapter version 0x%x, "
"LIC version 0x%x, "
"FC link speed %d Gb/s\n",
zfcp_get_busid_by_adapter(adapter),
(wwn_t) fc_host_node_name(shost),
(wwn_t) fc_host_port_name(shost),
fc_host_port_id(shost),
adapter->hydra_version,
adapter->fsf_lic_version,
fc_host_speed(shost));
if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) {
ZFCP_LOG_NORMAL("error: the adapter %s "
"only supports newer control block "
......@@ -2114,8 +2115,10 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req);
return -EIO;
case FC_PORTTYPE_NPORT:
ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
"network detected at adapter %s.\n",
if (fsf_req->erp_action)
ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
"network detected at adapter "
"%s.\n",
zfcp_get_busid_by_adapter(adapter));
break;
default:
......
......@@ -213,6 +213,7 @@
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
/* host connection features */
#define FSF_FEATURE_NPIV_MODE 0x00000001
......@@ -340,6 +341,15 @@ struct fsf_qtcb_prefix {
u8 res1[20];
} __attribute__ ((packed));
struct fsf_statistics_info {
u64 input_req;
u64 output_req;
u64 control_req;
u64 input_mb;
u64 output_mb;
u64 seconds_act;
} __attribute__ ((packed));
union fsf_status_qual {
u8 byte[FSF_STATUS_QUALIFIER_SIZE];
u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
......@@ -436,7 +446,8 @@ struct fsf_qtcb_bottom_config {
u32 hardware_version;
u8 serial_number[32];
struct fsf_nport_serv_param plogi_payload;
u8 res4[160];
struct fsf_statistics_info stat_info;
u8 res4[112];
} __attribute__ ((packed));
struct fsf_qtcb_bottom_port {
......@@ -469,7 +480,10 @@ struct fsf_qtcb_bottom_port {
u64 control_requests;
u64 input_mb; /* where 1 MByte == 1.000.000 Bytes */
u64 output_mb; /* where 1 MByte == 1.000.000 Bytes */
u8 res2[256];
u8 cp_util;
u8 cb_util;
u8 a_util;
u8 res2[253];
} __attribute__ ((packed));
union fsf_qtcb_bottom {
......
......@@ -40,6 +40,7 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
unsigned int, unsigned int);
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
static struct device_attribute *zfcp_a_stats_attrs[];
struct zfcp_data zfcp_data = {
.scsi_host_template = {
......@@ -61,6 +62,7 @@ struct zfcp_data zfcp_data = {
.use_clustering = 1,
.sdev_attrs = zfcp_sysfs_sdev_attrs,
.max_sectors = ZFCP_MAX_SECTORS,
.shost_attrs = zfcp_a_stats_attrs,
},
.driver_version = ZFCP_VERSION,
};
......@@ -809,4 +811,116 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
NULL
};
static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *scsi_host = dev_to_shost(dev);
struct fsf_qtcb_bottom_port *qtcb_port;
int retval;
struct zfcp_adapter *adapter;
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
return -EOPNOTSUPP;
qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
if (!qtcb_port)
return -ENOMEM;
retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
if (!retval)
retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
qtcb_port->cb_util, qtcb_port->a_util);
kfree(qtcb_port);
return retval;
}
static int zfcp_sysfs_adapter_ex_config(struct device *dev,
struct fsf_statistics_info *stat_inf)
{
int retval;
struct fsf_qtcb_bottom_config *qtcb_config;
struct Scsi_Host *scsi_host = dev_to_shost(dev);
struct zfcp_adapter *adapter;
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
return -EOPNOTSUPP;
qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
GFP_KERNEL);
if (!qtcb_config)
return -ENOMEM;
retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
if (!retval)
*stat_inf = qtcb_config->stat_info;
kfree(qtcb_config);
return retval;
}
static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct fsf_statistics_info stat_info;
int retval;
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
if (retval)
return retval;
return sprintf(buf, "%llu %llu %llu\n",
(unsigned long long) stat_info.input_req,
(unsigned long long) stat_info.output_req,
(unsigned long long) stat_info.control_req);
}
static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct fsf_statistics_info stat_info;
int retval;
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
if (retval)
return retval;
return sprintf(buf, "%llu %llu\n",
(unsigned long long) stat_info.input_mb,
(unsigned long long) stat_info.output_mb);
}
static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct fsf_statistics_info stat_info;
int retval;
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
if (retval)
return retval;
return sprintf(buf, "%llu\n",
(unsigned long long) stat_info.seconds_act);
}
static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
static DEVICE_ATTR(seconds_active, S_IRUGO,
zfcp_sysfs_adapter_sec_active_show, NULL);
static struct device_attribute *zfcp_a_stats_attrs[] = {
&dev_attr_utilization,
&dev_attr_requests,
&dev_attr_megabytes,
&dev_attr_seconds_active,
NULL
};
#undef ZFCP_LOG_AREA
......@@ -1499,7 +1499,7 @@ static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb)
thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
ioport = ((struct sccb_card *)pCurrCard)->ioPort;
if ((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN)) {
if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
p_Sccb->HostStatus = SCCB_COMPLETE;
p_Sccb->SccbStatus = SCCB_ERROR;
......
......@@ -1677,6 +1677,16 @@ config MAC_SCSI
SCSI-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
config SCSI_MAC_ESP
tristate "Macintosh NCR53c9[46] SCSI"
depends on MAC && SCSI
help
This is the NCR 53c9x SCSI controller found on most of the 68040
based Macintoshes.
To compile this driver as a module, choose M here: the module
will be called mac_esp.
config MVME147_SCSI
bool "WD33C93 SCSI driver for MVME147"
depends on MVME147 && SCSI=y
......
......@@ -46,6 +46,7 @@ obj-$(CONFIG_MVME147_SCSI) += mvme147.o wd33c93.o
obj-$(CONFIG_SGIWD93_SCSI) += sgiwd93.o wd33c93.o
obj-$(CONFIG_ATARI_SCSI) += atari_scsi.o
obj-$(CONFIG_MAC_SCSI) += mac_scsi.o
obj-$(CONFIG_SCSI_MAC_ESP) += esp_scsi.o mac_esp.o
obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o sun3_scsi_vme.o
obj-$(CONFIG_MVME16x_SCSI) += 53c700.o mvme16x_scsi.o
obj-$(CONFIG_BVME6000_SCSI) += 53c700.o bvme6000_scsi.o
......
......@@ -1432,15 +1432,10 @@ static void run(struct work_struct *work)
*/
static irqreturn_t intr(int irqno, void *dev_id)
{
struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id;
struct Scsi_Host *shpnt = dev_id;
unsigned long flags;
unsigned char rev, dmacntrl0;
if (!shpnt) {
printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
return IRQ_NONE;
}
/*
* Read a couple of registers that are known to not be all 1's. If
* we read all 1's (-1), that means that either:
......
......@@ -153,8 +153,6 @@ struct aha1542_hostdata {
#define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
static struct Scsi_Host *aha_host[7]; /* One for each IRQ level (9-15) */
static DEFINE_SPINLOCK(aha1542_lock);
......@@ -163,8 +161,7 @@ static DEFINE_SPINLOCK(aha1542_lock);
static void setup_mailboxes(int base_io, struct Scsi_Host *shpnt);
static int aha1542_restart(struct Scsi_Host *shost);
static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id);
static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id);
static void aha1542_intr_handle(struct Scsi_Host *shost);
#define aha1542_intr_reset(base) outb(IRST, CONTROL(base))
......@@ -404,23 +401,19 @@ static int __init aha1542_test_port(int bse, struct Scsi_Host *shpnt)
}
/* A quick wrapper for do_aha1542_intr_handle to grab the spin lock */
static irqreturn_t do_aha1542_intr_handle(int irq, void *dev_id)
static irqreturn_t do_aha1542_intr_handle(int dummy, void *dev_id)
{
unsigned long flags;
struct Scsi_Host *shost;
shost = aha_host[irq - 9];
if (!shost)
panic("Splunge!");
struct Scsi_Host *shost = dev_id;
spin_lock_irqsave(shost->host_lock, flags);
aha1542_intr_handle(shost, dev_id);
aha1542_intr_handle(shost);
spin_unlock_irqrestore(shost->host_lock, flags);
return IRQ_HANDLED;
}
/* A "high" level interrupt handler */
static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id)
static void aha1542_intr_handle(struct Scsi_Host *shost)
{
void (*my_done) (Scsi_Cmnd *) = NULL;
int errstatus, mbi, mbo, mbistatus;
......@@ -1197,7 +1190,8 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
spin_lock_irqsave(&aha1542_lock, flags);
if (request_irq(irq_level, do_aha1542_intr_handle, 0, "aha1542", NULL)) {
if (request_irq(irq_level, do_aha1542_intr_handle, 0,
"aha1542", shpnt)) {
printk(KERN_ERR "Unable to allocate IRQ for adaptec controller.\n");
spin_unlock_irqrestore(&aha1542_lock, flags);
goto unregister;
......@@ -1205,7 +1199,7 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
if (dma_chan != 0xFF) {
if (request_dma(dma_chan, "aha1542")) {
printk(KERN_ERR "Unable to allocate DMA channel for Adaptec.\n");
free_irq(irq_level, NULL);
free_irq(irq_level, shpnt);
spin_unlock_irqrestore(&aha1542_lock, flags);
goto unregister;
}
......@@ -1214,7 +1208,7 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
enable_dma(dma_chan);
}
}
aha_host[irq_level - 9] = shpnt;
shpnt->this_id = scsi_id;
shpnt->unique_id = base_io;
shpnt->io_port = base_io;
......@@ -1276,7 +1270,7 @@ static int __init aha1542_detect(struct scsi_host_template * tpnt)
static int aha1542_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
free_irq(shost->irq, shost);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
......
......@@ -815,7 +815,7 @@ struct ahd_tmode_tstate {
struct ahd_phase_table_entry {
uint8_t phase;
uint8_t mesg_out; /* Message response to parity errors */
char *phasemsg;
const char *phasemsg;
};
/************************** Serial EEPROM Format ******************************/
......@@ -1314,7 +1314,7 @@ typedef int (ahd_device_setup_t)(struct ahd_softc *);
struct ahd_pci_identity {
uint64_t full_id;
uint64_t id_mask;
char *name;
const char *name;
ahd_device_setup_t *setup;
};
......@@ -1322,7 +1322,7 @@ struct ahd_pci_identity {
struct aic7770_identity {
uint32_t full_id;
uint32_t id_mask;
char *name;
const char *name;
ahd_device_setup_t *setup;
};
extern struct aic7770_identity aic7770_ident_table [];
......@@ -1333,12 +1333,11 @@ extern const int ahd_num_aic7770_devs;
/*************************** Function Declarations ****************************/
/******************************************************************************/
void ahd_reset_cmds_pending(struct ahd_softc *ahd);
/***************************** PCI Front End *********************************/
struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
const struct ahd_pci_identity *ahd_find_pci_device(ahd_dev_softc_t);
int ahd_pci_config(struct ahd_softc *,
struct ahd_pci_identity *);
const struct ahd_pci_identity *);
int ahd_pci_test_register_access(struct ahd_softc *);
#ifdef CONFIG_PM
void ahd_pci_suspend(struct ahd_softc *);
......@@ -1376,16 +1375,6 @@ int ahd_write_flexport(struct ahd_softc *ahd,
int ahd_read_flexport(struct ahd_softc *ahd, u_int addr,
uint8_t *value);
/*************************** Interrupt Services *******************************/
void ahd_run_qoutfifo(struct ahd_softc *ahd);
#ifdef AHD_TARGET_MODE
void ahd_run_tqinfifo(struct ahd_softc *ahd, int paused);
#endif
void ahd_handle_hwerrint(struct ahd_softc *ahd);
void ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat);
void ahd_handle_scsiint(struct ahd_softc *ahd,
u_int intstat);
/***************************** Error Recovery *********************************/
typedef enum {
SEARCH_COMPLETE,
......@@ -1479,7 +1468,7 @@ extern uint32_t ahd_debug;
void ahd_print_devinfo(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo);
void ahd_dump_card_state(struct ahd_softc *ahd);
int ahd_print_register(ahd_reg_parse_entry_t *table,
int ahd_print_register(const ahd_reg_parse_entry_t *table,
u_int num_entries,
const char *name,
u_int address,
......
......@@ -198,6 +198,7 @@ register SEQINTCODE {
register CLRINT {
address 0x003
access_mode WO
count 19
field CLRHWERRINT 0x80 /* Rev B or greater */
field CLRBRKADRINT 0x40
field CLRSWTMINT 0x20
......@@ -245,6 +246,7 @@ register CLRERR {
register HCNTRL {
address 0x005
access_mode RW
count 12
field SEQ_RESET 0x80 /* Rev B or greater */
field POWRDN 0x40
field SWINT 0x10
......@@ -262,6 +264,7 @@ register HNSCB_QOFF {
address 0x006
access_mode RW
size 2
count 2
}
/*
......@@ -270,6 +273,7 @@ register HNSCB_QOFF {
register HESCB_QOFF {
address 0x008
access_mode RW
count 2
}
/*
......@@ -287,6 +291,7 @@ register HS_MAILBOX {
*/
register SEQINTSTAT {
address 0x00C
count 1
access_mode RO
field SEQ_SWTMRTO 0x10
field SEQ_SEQINT 0x08
......@@ -332,6 +337,7 @@ register SNSCB_QOFF {
*/
register SESCB_QOFF {
address 0x012
count 2
access_mode RW
modes M_CCHAN
}
......@@ -397,6 +403,7 @@ register DFCNTRL {
address 0x019
access_mode RW
modes M_DFF0, M_DFF1
count 11
field PRELOADEN 0x80
field SCSIENWRDIS 0x40 /* Rev B only. */
field SCSIEN 0x20
......@@ -415,6 +422,7 @@ register DFCNTRL {
*/
register DSCOMMAND0 {
address 0x019
count 1
access_mode RW
modes M_CFG
field CACHETHEN 0x80 /* Cache Threshold enable */
......@@ -580,6 +588,7 @@ register DFF_THRSH {
address 0x088
access_mode RW
modes M_CFG
count 1
field WR_DFTHRSH 0x70 {
WR_DFTHRSH_MIN,
WR_DFTHRSH_25,
......@@ -800,6 +809,7 @@ register PCIXCTL {
address 0x093
access_mode RW
modes M_CFG
count 1
field SERRPULSE 0x80
field UNEXPSCIEN 0x20
field SPLTSMADIS 0x10
......@@ -844,6 +854,7 @@ register DCHSPLTSTAT0 {
address 0x096
access_mode RW
modes M_DFF0, M_DFF1
count 2
field STAETERM 0x80
field SCBCERR 0x40
field SCADERR 0x20
......@@ -895,6 +906,7 @@ register DCHSPLTSTAT1 {
address 0x097
access_mode RW
modes M_DFF0, M_DFF1
count 2
field RXDATABUCKET 0x01
}
......@@ -1048,6 +1060,7 @@ register SGSPLTSTAT0 {
address 0x09E
access_mode RW
modes M_DFF0, M_DFF1
count 2
field STAETERM 0x80
field SCBCERR 0x40
field SCADERR 0x20
......@@ -1065,6 +1078,7 @@ register SGSPLTSTAT1 {
address 0x09F
access_mode RW
modes M_DFF0, M_DFF1
count 2
field RXDATABUCKET 0x01
}
......@@ -1086,6 +1100,7 @@ register DF0PCISTAT {
address 0x0A0
access_mode RW
modes M_CFG
count 1
field DPE 0x80
field SSE 0x40
field RMA 0x20
......@@ -1184,6 +1199,7 @@ register TARGPCISTAT {
address 0x0A7
access_mode RW
modes M_CFG
count 5
field DPE 0x80
field SSE 0x40
field STA 0x08
......@@ -1198,6 +1214,7 @@ register LQIN {
address 0x020
access_mode RW
size 20
count 2
modes M_DFF0, M_DFF1, M_SCSI
}
......@@ -1229,6 +1246,7 @@ register LUNPTR {
address 0x022
access_mode RW
modes M_CFG
count 2
}
/*
......@@ -1259,6 +1277,7 @@ register CMDLENPTR {
address 0x025
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1270,6 +1289,7 @@ register ATTRPTR {
address 0x026
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1281,6 +1301,7 @@ register FLAGPTR {
address 0x027
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1291,6 +1312,7 @@ register CMDPTR {
address 0x028
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1301,6 +1323,7 @@ register QNEXTPTR {
address 0x029
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1323,6 +1346,7 @@ register ABRTBYTEPTR {
address 0x02B
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1333,6 +1357,7 @@ register ABRTBITPTR {
address 0x02C
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1370,6 +1395,7 @@ register LUNLEN {
address 0x030
access_mode RW
modes M_CFG
count 2
mask ILUNLEN 0x0F
mask TLUNLEN 0xF0
}
......@@ -1383,6 +1409,7 @@ register CDBLIMIT {
address 0x031
access_mode RW
modes M_CFG
count 1
}
/*
......@@ -1394,6 +1421,7 @@ register MAXCMD {
address 0x032
access_mode RW
modes M_CFG
count 9
}
/*
......@@ -1458,6 +1486,7 @@ register LQCTL1 {
address 0x038
access_mode RW
modes M_DFF0, M_DFF1, M_SCSI
count 2
field PCI2PCI 0x04
field SINGLECMD 0x02
field ABORTPENDING 0x01
......@@ -1470,6 +1499,7 @@ register LQCTL2 {
address 0x039
access_mode RW
modes M_DFF0, M_DFF1, M_SCSI
count 5
field LQIRETRY 0x80
field LQICONTINUE 0x40
field LQITOIDLE 0x20
......@@ -1528,6 +1558,7 @@ register SCSISEQ1 {
address 0x03B
access_mode RW
modes M_DFF0, M_DFF1, M_SCSI
count 8
field MANUALCTL 0x40
field ENSELI 0x20
field ENRSELI 0x10
......@@ -1667,6 +1698,9 @@ register SCSISIGO {
}
}
/*
* SCSI Control Signal In
*/
register SCSISIGI {
address 0x041
access_mode RO
......@@ -1703,6 +1737,7 @@ register MULTARGID {
access_mode RW
modes M_CFG
size 2
count 2
}
/*
......@@ -1758,6 +1793,7 @@ register TARGIDIN {
address 0x048
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 2
field CLKOUT 0x80
field TARGID 0x0F
}
......@@ -1798,6 +1834,7 @@ register OPTIONMODE {
address 0x04A
access_mode RW
modes M_CFG
count 4
field BIOSCANCTL 0x80
field AUTOACKEN 0x40
field BIASCANCTL 0x20
......@@ -1850,6 +1887,7 @@ register SIMODE0 {
address 0x04B
access_mode RW
modes M_CFG
count 8
field ENSELDO 0x40
field ENSELDI 0x20
field ENSELINGO 0x10
......@@ -1945,6 +1983,7 @@ register PERRDIAG {
address 0x04E
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 3
field HIZERO 0x80
field HIPERR 0x40
field PREVPHASE 0x20
......@@ -1962,6 +2001,7 @@ register LQISTATE {
address 0x04E
access_mode RO
modes M_CFG
count 6
}
/*
......@@ -1971,6 +2011,7 @@ register SOFFCNT {
address 0x04F
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 1
}
/*
......@@ -1980,6 +2021,7 @@ register LQOSTATE {
address 0x04F
access_mode RO
modes M_CFG
count 2
}
/*
......@@ -1989,6 +2031,7 @@ register LQISTAT0 {
address 0x050
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 2
field LQIATNQAS 0x20
field LQICRCT1 0x10
field LQICRCT2 0x08
......@@ -2004,6 +2047,7 @@ register CLRLQIINT0 {
address 0x050
access_mode WO
modes M_DFF0, M_DFF1, M_SCSI
count 1
field CLRLQIATNQAS 0x20
field CLRLQICRCT1 0x10
field CLRLQICRCT2 0x08
......@@ -2019,6 +2063,7 @@ register LQIMODE0 {
address 0x050
access_mode RW
modes M_CFG
count 3
field ENLQIATNQASK 0x20
field ENLQICRCT1 0x10
field ENLQICRCT2 0x08
......@@ -2034,6 +2079,7 @@ register LQISTAT1 {
address 0x051
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 3
field LQIPHASE_LQ 0x80
field LQIPHASE_NLQ 0x40
field LQIABORT 0x20
......@@ -2051,6 +2097,7 @@ register CLRLQIINT1 {
address 0x051
access_mode WO
modes M_DFF0, M_DFF1, M_SCSI
count 4
field CLRLQIPHASE_LQ 0x80
field CLRLQIPHASE_NLQ 0x40
field CLRLIQABORT 0x20
......@@ -2068,6 +2115,7 @@ register LQIMODE1 {
address 0x051
access_mode RW
modes M_CFG
count 4
field ENLQIPHASE_LQ 0x80 /* LQIPHASE1 */
field ENLQIPHASE_NLQ 0x40 /* LQIPHASE2 */
field ENLIQABORT 0x20
......@@ -2102,6 +2150,7 @@ register SSTAT3 {
address 0x053
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 3
field NTRAMPERR 0x02
field OSRAMPERR 0x01
}
......@@ -2113,6 +2162,7 @@ register CLRSINT3 {
address 0x053
access_mode WO
modes M_DFF0, M_DFF1, M_SCSI
count 3
field CLRNTRAMPERR 0x02
field CLROSRAMPERR 0x01
}
......@@ -2124,6 +2174,7 @@ register SIMODE3 {
address 0x053
access_mode RW
modes M_CFG
count 4
field ENNTRAMPERR 0x02
field ENOSRAMPERR 0x01
}
......@@ -2135,6 +2186,7 @@ register LQOSTAT0 {
address 0x054
access_mode RO
modes M_DFF0, M_DFF1, M_SCSI
count 2
field LQOTARGSCBPERR 0x10
field LQOSTOPT2 0x08
field LQOATNLQ 0x04
......@@ -2149,6 +2201,7 @@ register CLRLQOINT0 {
address 0x054
access_mode WO
modes M_DFF0, M_DFF1, M_SCSI
count 3
field CLRLQOTARGSCBPERR 0x10
field CLRLQOSTOPT2 0x08
field CLRLQOATNLQ 0x04
......@@ -2163,6 +2216,7 @@ register LQOMODE0 {
address 0x054
access_mode RW
modes M_CFG
count 4
field ENLQOTARGSCBPERR 0x10
field ENLQOSTOPT2 0x08
field ENLQOATNLQ 0x04
......@@ -2191,6 +2245,7 @@ register CLRLQOINT1 {
address 0x055
access_mode WO
modes M_DFF0, M_DFF1, M_SCSI
count 7
field CLRLQOINITSCBPERR 0x10
field CLRLQOSTOPI2 0x08
field CLRLQOBADQAS 0x04
......@@ -2205,6 +2260,7 @@ register LQOMODE1 {
address 0x055
access_mode RW
modes M_CFG
count 4
field ENLQOINITSCBPERR 0x10
field ENLQOSTOPI2 0x08
field ENLQOBADQAS 0x04
......@@ -2232,6 +2288,7 @@ register OS_SPACE_CNT {
address 0x056
access_mode RO
modes M_CFG
count 2
}
/*
......@@ -2286,13 +2343,19 @@ register NEXTSCB {
modes M_SCSI
}
/* Rev B only. */
/*
* LQO SCSI Control
* (Rev B only.)
*/
register LQOSCSCTL {
address 0x05A
access_mode RW
size 1
modes M_CFG
count 1
field LQOH2A_VERSION 0x80
field LQOBUSETDLY 0x40
field LQONOHOLDLACK 0x02
field LQONOCHKOVER 0x01
}
......@@ -2459,6 +2522,7 @@ register NEGPERIOD {
address 0x061
access_mode RW
modes M_SCSI
count 1
}
/*
......@@ -2478,6 +2542,7 @@ register NEGOFFSET {
address 0x062
access_mode RW
modes M_SCSI
count 1
}
/*
......@@ -2487,6 +2552,7 @@ register NEGPPROPTS {
address 0x063
access_mode RW
modes M_SCSI
count 1
field PPROPT_PACE 0x08
field PPROPT_QAS 0x04
field PPROPT_DT 0x02
......@@ -2516,12 +2582,19 @@ register ANNEXCOL {
address 0x065
access_mode RW
modes M_SCSI
count 7
}
/*
* SCSI Check
* (Rev. B only)
*/
register SCSCHKN {
address 0x066
access_mode RW
modes M_CFG
count 1
field BIDICHKDIS 0x80
field STSELSKIDDIS 0x40
field CURRFIFODEF 0x20
field WIDERESEN 0x10
......@@ -2561,6 +2634,7 @@ register ANNEXDAT {
address 0x066
access_mode RW
modes M_SCSI
count 3
}
/*
......@@ -2596,6 +2670,7 @@ register TOWNID {
address 0x069
access_mode RW
modes M_SCSI
count 2
}
/*
......@@ -2737,6 +2812,7 @@ register SCBAUTOPTR {
address 0x0AB
access_mode RW
modes M_CFG
count 1
field AUSCBPTR_EN 0x80
field SCBPTR_ADDR 0x38
field SCBPTR_OFF 0x07
......@@ -2881,6 +2957,7 @@ register BRDDAT {
address 0x0B8
access_mode RW
modes M_SCSI
count 2
}
/*
......@@ -2890,6 +2967,7 @@ register BRDCTL {
address 0x0B9
access_mode RW
modes M_SCSI
count 7
field FLXARBACK 0x80
field FLXARBREQ 0x40
field BRDADDR 0x38
......@@ -2905,6 +2983,7 @@ register SEEADR {
address 0x0BA
access_mode RW
modes M_SCSI
count 4
}
/*
......@@ -2915,6 +2994,7 @@ register SEEDAT {
access_mode RW
size 2
modes M_SCSI
count 4
}
/*
......@@ -2924,6 +3004,7 @@ register SEESTAT {
address 0x0BE
access_mode RO
modes M_SCSI
count 1
field INIT_DONE 0x80
field SEEOPCODE 0x70
field LDALTID_L 0x08
......@@ -2939,6 +3020,7 @@ register SEECTL {
address 0x0BE
access_mode RW
modes M_SCSI
count 4
field SEEOPCODE 0x70 {
SEEOP_ERASE 0x70,
SEEOP_READ 0x60,
......@@ -3000,6 +3082,7 @@ register DSPDATACTL {
address 0x0C1
access_mode RW
modes M_CFG
count 3
field BYPASSENAB 0x80
field DESQDIS 0x10
field RCVROFFSTDIS 0x04
......@@ -3058,6 +3141,7 @@ register DSPSELECT {
address 0x0C4
access_mode RW
modes M_CFG
count 1
field AUTOINCEN 0x80
field DSPSEL 0x1F
}
......@@ -3071,6 +3155,7 @@ register WRTBIASCTL {
address 0x0C5
access_mode WO
modes M_CFG
count 3
field AUTOXBCDIS 0x80
field XMITMANVAL 0x3F
}
......@@ -3196,7 +3281,8 @@ register OVLYADDR {
*/
register SEQCTL0 {
address 0x0D6
access_mode RW
access_mode RW
count 11
field PERRORDIS 0x80
field PAUSEDIS 0x40
field FAILDIS 0x20
......@@ -3226,7 +3312,8 @@ register SEQCTL1 {
*/
register FLAGS {
address 0x0D8
access_mode RO
access_mode RO
count 23
field ZERO 0x02
field CARRY 0x01
}
......@@ -3255,7 +3342,8 @@ register SEQINTCTL {
*/
register SEQRAM {
address 0x0DA
access_mode RW
access_mode RW
count 2
}
/*
......@@ -3266,6 +3354,7 @@ register PRGMCNT {
address 0x0DE
access_mode RW
size 2
count 5
}
/*
......@@ -3273,7 +3362,7 @@ register PRGMCNT {
*/
register ACCUM {
address 0x0E0
access_mode RW
access_mode RW
accumulator
}
......@@ -3401,6 +3490,7 @@ register INTVEC1_ADDR {
access_mode RW
size 2
modes M_CFG
count 1
}
/*
......@@ -3412,6 +3502,7 @@ register CURADDR {
access_mode RW
size 2
modes M_SCSI
count 2
}
/*
......@@ -3423,6 +3514,7 @@ register INTVEC2_ADDR {
access_mode RW
size 2
modes M_CFG
count 1
}
/*
......@@ -3579,6 +3671,7 @@ scratch_ram {
/* Parameters for DMA Logic */
DMAPARAMS {
size 1
count 8
field PRELOADEN 0x80
field WIDEODD 0x40
field SCSIEN 0x20
......@@ -3648,9 +3741,11 @@ scratch_ram {
*/
KERNEL_TQINPOS {
size 1
count 1
}
TQINPOS {
TQINPOS {
size 1
count 8
}
/*
* Base address of our shared data with the kernel driver in host
......@@ -3681,6 +3776,7 @@ scratch_ram {
}
ARG_2 {
size 1
count 1
alias RETURN_2
}
......@@ -3698,6 +3794,7 @@ scratch_ram {
*/
SCSISEQ_TEMPLATE {
size 1
count 7
field MANUALCTL 0x40
field ENSELI 0x20
field ENRSELI 0x10
......@@ -3711,6 +3808,7 @@ scratch_ram {
*/
INITIATOR_TAG {
size 1
count 1
}
SEQ_FLAGS2 {
......@@ -3777,6 +3875,7 @@ scratch_ram {
*/
CMDSIZE_TABLE {
size 8
count 8
}
/*
* When an SCB with the MK_MESSAGE flag is
......@@ -3803,8 +3902,8 @@ scratch_ram {
/************************* Hardware SCB Definition ****************************/
scb {
address 0x180
size 64
modes 0, 1, 2, 3
size 64
modes 0, 1, 2, 3
SCB_RESIDUAL_DATACNT {
size 4
alias SCB_CDB_STORE
......
此差异已折叠。
......@@ -193,7 +193,7 @@ struct ahd_linux_iocell_opts
#define AIC79XX_PRECOMP_INDEX 0
#define AIC79XX_SLEWRATE_INDEX 1
#define AIC79XX_AMPLITUDE_INDEX 2
static struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
{
AIC79XX_DEFAULT_IOOPTS,
AIC79XX_DEFAULT_IOOPTS,
......@@ -369,10 +369,167 @@ static void ahd_release_simq(struct ahd_softc *ahd);
static int ahd_linux_unit;
/************************** OS Utility Wrappers *******************************/
void ahd_delay(long);
void
ahd_delay(long usec)
{
/*
* udelay on Linux can have problems for
* multi-millisecond waits. Wait at most
* 1024us per call.
*/
while (usec > 0) {
udelay(usec % 1024);
usec -= 1024;
}
}
/***************************** Low Level I/O **********************************/
uint8_t ahd_inb(struct ahd_softc * ahd, long port);
void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
void ahd_outw_atomic(struct ahd_softc * ahd,
long port, uint16_t val);
void ahd_outsb(struct ahd_softc * ahd, long port,
uint8_t *, int count);
void ahd_insb(struct ahd_softc * ahd, long port,
uint8_t *, int count);
uint8_t
ahd_inb(struct ahd_softc * ahd, long port)
{
uint8_t x;
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readb(ahd->bshs[0].maddr + port);
} else {
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
mb();
return (x);
}
#if 0 /* unused */
static uint16_t
ahd_inw_atomic(struct ahd_softc * ahd, long port)
{
uint8_t x;
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readw(ahd->bshs[0].maddr + port);
} else {
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
mb();
return (x);
}
#endif
void
ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
{
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writeb(val, ahd->bshs[0].maddr + port);
} else {
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
mb();
}
void
ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
{
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writew(val, ahd->bshs[0].maddr + port);
} else {
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
mb();
}
void
ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
{
int i;
/*
* There is probably a more efficient way to do this on Linux
* but we don't use this for anything speed critical and this
* should work.
*/
for (i = 0; i < count; i++)
ahd_outb(ahd, port, *array++);
}
void
ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
{
int i;
/*
* There is probably a more efficient way to do this on Linux
* but we don't use this for anything speed critical and this
* should work.
*/
for (i = 0; i < count; i++)
*array++ = ahd_inb(ahd, port);
}
/******************************* PCI Routines *********************************/
uint32_t
ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
{
switch (width) {
case 1:
{
uint8_t retval;
pci_read_config_byte(pci, reg, &retval);
return (retval);
}
case 2:
{
uint16_t retval;
pci_read_config_word(pci, reg, &retval);
return (retval);
}
case 4:
{
uint32_t retval;
pci_read_config_dword(pci, reg, &retval);
return (retval);
}
default:
panic("ahd_pci_read_config: Read size too big");
/* NOTREACHED */
return (0);
}
}
void
ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
{
switch (width) {
case 1:
pci_write_config_byte(pci, reg, value);
break;
case 2:
pci_write_config_word(pci, reg, value);
break;
case 4:
pci_write_config_dword(pci, reg, value);
break;
default:
panic("ahd_pci_write_config: Write size too big");
/* NOTREACHED */
}
}
/****************************** Inlines ***************************************/
static __inline void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
static void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
static __inline void
static void
ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
{
struct scsi_cmnd *cmd;
......@@ -400,13 +557,11 @@ ahd_linux_info(struct Scsi_Host *host)
bp = &buffer[0];
ahd = *(struct ahd_softc **)host->hostdata;
memset(bp, 0, sizeof(buffer));
strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev ");
strcat(bp, AIC79XX_DRIVER_VERSION);
strcat(bp, "\n");
strcat(bp, " <");
strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev " AIC79XX_DRIVER_VERSION "\n"
" <");
strcat(bp, ahd->description);
strcat(bp, ">\n");
strcat(bp, " ");
strcat(bp, ">\n"
" ");
ahd_controller_info(ahd, ahd_info);
strcat(bp, ahd_info);
......@@ -432,7 +587,7 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
return rtn;
}
static inline struct scsi_target **
static struct scsi_target **
ahd_linux_target_in_softc(struct scsi_target *starget)
{
struct ahd_softc *ahd =
......@@ -991,7 +1146,7 @@ aic79xx_setup(char *s)
char *p;
char *end;
static struct {
static const struct {
const char *name;
uint32_t *flag;
} options[] = {
......@@ -1223,7 +1378,7 @@ ahd_platform_init(struct ahd_softc *ahd)
* Lookup and commit any modified IO Cell options.
*/
if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
struct ahd_linux_iocell_opts *iocell_opts;
const struct ahd_linux_iocell_opts *iocell_opts;
iocell_opts = &aic79xx_iocell_info[ahd->unit];
if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
......@@ -2613,7 +2768,7 @@ static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
uint8_t precomp;
if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
struct ahd_linux_iocell_opts *iocell_opts;
const struct ahd_linux_iocell_opts *iocell_opts;
iocell_opts = &aic79xx_iocell_info[ahd->unit];
precomp = iocell_opts->precomp;
......
......@@ -222,22 +222,6 @@ typedef struct timer_list ahd_timer_t;
/***************************** Timer Facilities *******************************/
#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, int usec,
ahd_callback_t *func, void *arg);
static __inline void
ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg)
{
struct ahd_softc *ahd;
ahd = (struct ahd_softc *)arg;
del_timer(timer);
timer->data = (u_long)arg;
timer->expires = jiffies + (usec * HZ)/1000000;
timer->function = (ahd_linux_callback_t*)func;
add_timer(timer);
}
/***************************** SMP support ************************************/
#include <linux/spinlock.h>
......@@ -376,7 +360,7 @@ struct ahd_platform_data {
#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 */
resource_size_t mem_busaddr; /* Mem Base Addr */
};
/************************** OS Utility Wrappers *******************************/
......@@ -386,111 +370,18 @@ struct ahd_platform_data {
#define malloc(size, type, flags) kmalloc(size, flags)
#define free(ptr, type) kfree(ptr)
static __inline void ahd_delay(long);
static __inline void
ahd_delay(long usec)
{
/*
* udelay on Linux can have problems for
* multi-millisecond waits. Wait at most
* 1024us per call.
*/
while (usec > 0) {
udelay(usec % 1024);
usec -= 1024;
}
}
void ahd_delay(long);
/***************************** Low Level I/O **********************************/
static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port);
static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port);
static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
static __inline void ahd_outw_atomic(struct ahd_softc * ahd,
uint8_t ahd_inb(struct ahd_softc * ahd, long port);
void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
void ahd_outw_atomic(struct ahd_softc * ahd,
long port, uint16_t val);
static __inline void ahd_outsb(struct ahd_softc * ahd, long port,
void ahd_outsb(struct ahd_softc * ahd, long port,
uint8_t *, int count);
static __inline void ahd_insb(struct ahd_softc * ahd, long port,
void ahd_insb(struct ahd_softc * ahd, long port,
uint8_t *, int count);
static __inline uint8_t
ahd_inb(struct ahd_softc * ahd, long port)
{
uint8_t x;
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readb(ahd->bshs[0].maddr + port);
} else {
x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
mb();
return (x);
}
static __inline uint16_t
ahd_inw_atomic(struct ahd_softc * ahd, long port)
{
uint8_t x;
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
x = readw(ahd->bshs[0].maddr + port);
} else {
x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
}
mb();
return (x);
}
static __inline void
ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
{
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writeb(val, ahd->bshs[0].maddr + port);
} else {
outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
mb();
}
static __inline void
ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
{
if (ahd->tags[0] == BUS_SPACE_MEMIO) {
writew(val, ahd->bshs[0].maddr + port);
} else {
outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
}
mb();
}
static __inline void
ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
{
int i;
/*
* There is probably a more efficient way to do this on Linux
* but we don't use this for anything speed critical and this
* should work.
*/
for (i = 0; i < count; i++)
ahd_outb(ahd, port, *array++);
}
static __inline void
ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
{
int i;
/*
* There is probably a more efficient way to do this on Linux
* but we don't use this for anything speed critical and this
* should work.
*/
for (i = 0; i < count; i++)
*array++ = ahd_inb(ahd, port);
}
/**************************** Initialization **********************************/
int ahd_linux_register_host(struct ahd_softc *,
struct scsi_host_template *);
......@@ -593,62 +484,12 @@ void ahd_linux_pci_exit(void);
int ahd_pci_map_registers(struct ahd_softc *ahd);
int ahd_pci_map_int(struct ahd_softc *ahd);
static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
int reg, int width);
static __inline uint32_t
ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
{
switch (width) {
case 1:
{
uint8_t retval;
pci_read_config_byte(pci, reg, &retval);
return (retval);
}
case 2:
{
uint16_t retval;
pci_read_config_word(pci, reg, &retval);
return (retval);
}
case 4:
{
uint32_t retval;
pci_read_config_dword(pci, reg, &retval);
return (retval);
}
default:
panic("ahd_pci_read_config: Read size too big");
/* NOTREACHED */
return (0);
}
}
static __inline void ahd_pci_write_config(ahd_dev_softc_t pci,
void ahd_pci_write_config(ahd_dev_softc_t pci,
int reg, uint32_t value,
int width);
static __inline void
ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
{
switch (width) {
case 1:
pci_write_config_byte(pci, reg, value);
break;
case 2:
pci_write_config_word(pci, reg, value);
break;
case 4:
pci_write_config_dword(pci, reg, value);
break;
default:
panic("ahd_pci_write_config: Write size too big");
/* NOTREACHED */
}
}
static __inline int ahd_get_pci_function(ahd_dev_softc_t);
static __inline int
ahd_get_pci_function(ahd_dev_softc_t pci)
......
......@@ -49,7 +49,7 @@
ID2C(x), \
ID2C(IDIROC(x))
static struct pci_device_id ahd_linux_pci_id_table[] = {
static const struct pci_device_id ahd_linux_pci_id_table[] = {
/* aic7901 based controllers */
ID(ID_AHA_29320A),
ID(ID_AHA_29320ALP),
......@@ -159,7 +159,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
char buf[80];
struct ahd_softc *ahd;
ahd_dev_softc_t pci;
struct ahd_pci_identity *entry;
const struct ahd_pci_identity *entry;
char *name;
int error;
struct device *dev = &pdev->dev;
......@@ -249,8 +249,8 @@ ahd_linux_pci_exit(void)
}
static int
ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
u_long *base2)
ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, resource_size_t *base,
resource_size_t *base2)
{
*base = pci_resource_start(ahd->dev_softc, 0);
/*
......@@ -272,11 +272,11 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
static int
ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd,
u_long *bus_addr,
resource_size_t *bus_addr,
uint8_t __iomem **maddr)
{
u_long start;
u_long base_page;
resource_size_t start;
resource_size_t base_page;
u_long base_offset;
int error = 0;
......@@ -310,7 +310,7 @@ int
ahd_pci_map_registers(struct ahd_softc *ahd)
{
uint32_t command;
u_long base;
resource_size_t base;
uint8_t __iomem *maddr;
int error;
......@@ -346,31 +346,32 @@ ahd_pci_map_registers(struct ahd_softc *ahd)
} else
command |= PCIM_CMD_MEMEN;
} else if (bootverbose) {
printf("aic79xx: PCI%d:%d:%d MEM region 0x%lx "
printf("aic79xx: PCI%d:%d:%d MEM region 0x%llx "
"unavailable. Cannot memory map device.\n",
ahd_get_pci_bus(ahd->dev_softc),
ahd_get_pci_slot(ahd->dev_softc),
ahd_get_pci_function(ahd->dev_softc),
base);
(unsigned long long)base);
}
if (maddr == NULL) {
u_long base2;
resource_size_t base2;
error = ahd_linux_pci_reserve_io_regions(ahd, &base, &base2);
if (error == 0) {
ahd->tags[0] = BUS_SPACE_PIO;
ahd->tags[1] = BUS_SPACE_PIO;
ahd->bshs[0].ioport = base;
ahd->bshs[1].ioport = base2;
ahd->bshs[0].ioport = (u_long)base;
ahd->bshs[1].ioport = (u_long)base2;
command |= PCIM_CMD_PORTEN;
} else {
printf("aic79xx: PCI%d:%d:%d IO regions 0x%lx and 0x%lx"
"unavailable. Cannot map device.\n",
printf("aic79xx: PCI%d:%d:%d IO regions 0x%llx and "
"0x%llx unavailable. Cannot map device.\n",
ahd_get_pci_bus(ahd->dev_softc),
ahd_get_pci_slot(ahd->dev_softc),
ahd_get_pci_function(ahd->dev_softc),
base, base2);
(unsigned long long)base,
(unsigned long long)base2);
}
}
ahd_pci_write_config(ahd->dev_softc, PCIR_COMMAND, command, 4);
......
......@@ -97,7 +97,7 @@ static ahd_device_setup_t ahd_aic7901A_setup;
static ahd_device_setup_t ahd_aic7902_setup;
static ahd_device_setup_t ahd_aic790X_setup;
static struct ahd_pci_identity ahd_pci_ident_table [] =
static const struct ahd_pci_identity ahd_pci_ident_table[] =
{
/* aic7901 based controllers */
{
......@@ -253,7 +253,7 @@ static void ahd_configure_termination(struct ahd_softc *ahd,
static void ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat);
static void ahd_pci_intr(struct ahd_softc *ahd);
struct ahd_pci_identity *
const struct ahd_pci_identity *
ahd_find_pci_device(ahd_dev_softc_t pci)
{
uint64_t full_id;
......@@ -261,7 +261,7 @@ ahd_find_pci_device(ahd_dev_softc_t pci)
uint16_t vendor;
uint16_t subdevice;
uint16_t subvendor;
struct ahd_pci_identity *entry;
const struct ahd_pci_identity *entry;
u_int i;
vendor = ahd_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
......@@ -292,7 +292,7 @@ ahd_find_pci_device(ahd_dev_softc_t pci)
}
int
ahd_pci_config(struct ahd_softc *ahd, struct ahd_pci_identity *entry)
ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
{
struct scb_data *shared_scb_data;
u_int command;
......
......@@ -57,7 +57,7 @@ static int ahd_proc_write_seeprom(struct ahd_softc *ahd,
* Table of syncrates that don't follow the "divisible by 4"
* rule. This table will be expanded in future SCSI specs.
*/
static struct {
static const struct {
u_int period_factor;
u_int period; /* in 100ths of ns */
} scsi_syncrates[] = {
......
......@@ -5,7 +5,7 @@
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#120 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#77 $
*/
static uint8_t seqprog[] = {
static const uint8_t seqprog[] = {
0xff, 0x02, 0x06, 0x78,
0x00, 0xea, 0x6e, 0x59,
0x01, 0xea, 0x04, 0x30,
......@@ -1027,7 +1027,7 @@ ahd_patch0_func(struct ahd_softc *ahd)
return (0);
}
static struct patch {
static const struct patch {
ahd_patch_func_t *patch_func;
uint32_t begin :10,
skip_instr :10,
......@@ -1166,7 +1166,7 @@ static struct patch {
{ ahd_patch23_func, 815, 11, 1 }
};
static struct cs {
static const struct cs {
uint16_t begin;
uint16_t end;
} critical_sections[] = {
......
......@@ -736,7 +736,7 @@ struct ahc_syncrate {
#define ST_SXFR 0x010 /* Rate Single Transition Only */
#define DT_SXFR 0x040 /* Rate Double Transition Only */
uint8_t period; /* Period to send to SCSI target */
char *rate;
const char *rate;
};
/* Safe and valid period for async negotiations. */
......@@ -1114,7 +1114,7 @@ typedef int (ahc_device_setup_t)(struct ahc_softc *);
struct ahc_pci_identity {
uint64_t full_id;
uint64_t id_mask;
char *name;
const char *name;
ahc_device_setup_t *setup;
};
......@@ -1133,15 +1133,11 @@ extern const int ahc_num_aic7770_devs;
/*************************** Function Declarations ****************************/
/******************************************************************************/
u_int ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl);
void ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl);
void ahc_busy_tcl(struct ahc_softc *ahc,
u_int tcl, u_int busyid);
/***************************** PCI Front End *********************************/
struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t);
const struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t);
int ahc_pci_config(struct ahc_softc *,
struct ahc_pci_identity *);
const struct ahc_pci_identity *);
int ahc_pci_test_register_access(struct ahc_softc *);
#ifdef CONFIG_PM
void ahc_pci_resume(struct ahc_softc *ahc);
......@@ -1155,9 +1151,6 @@ int aic7770_config(struct ahc_softc *ahc,
/************************** SCB and SCB queue management **********************/
int ahc_probe_scbs(struct ahc_softc *);
void ahc_run_untagged_queues(struct ahc_softc *ahc);
void ahc_run_untagged_queue(struct ahc_softc *ahc,
struct scb_tailq *queue);
void ahc_qinfifo_requeue_tail(struct ahc_softc *ahc,
struct scb *scb);
int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb,
......@@ -1178,22 +1171,8 @@ int ahc_resume(struct ahc_softc *ahc);
#endif
void ahc_set_unit(struct ahc_softc *, int);
void ahc_set_name(struct ahc_softc *, char *);
void ahc_alloc_scbs(struct ahc_softc *ahc);
void ahc_free(struct ahc_softc *ahc);
int ahc_reset(struct ahc_softc *ahc, int reinit);
void ahc_shutdown(void *arg);
/*************************** Interrupt Services *******************************/
void ahc_clear_intstat(struct ahc_softc *ahc);
void ahc_run_qoutfifo(struct ahc_softc *ahc);
#ifdef AHC_TARGET_MODE
void ahc_run_tqinfifo(struct ahc_softc *ahc, int paused);
#endif
void ahc_handle_brkadrint(struct ahc_softc *ahc);
void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat);
void ahc_handle_scsiint(struct ahc_softc *ahc,
u_int intstat);
void ahc_clear_critical_section(struct ahc_softc *ahc);
/***************************** Error Recovery *********************************/
typedef enum {
......@@ -1214,36 +1193,19 @@ int ahc_search_disc_list(struct ahc_softc *ahc, int target,
char channel, int lun, u_int tag,
int stop_on_first, int remove,
int save_state);
void ahc_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
int ahc_reset_channel(struct ahc_softc *ahc, char channel,
int initiate_reset);
int ahc_abort_scbs(struct ahc_softc *ahc, int target,
char channel, int lun, u_int tag,
role_t role, uint32_t status);
void ahc_restart(struct ahc_softc *ahc);
void ahc_calc_residual(struct ahc_softc *ahc,
struct scb *scb);
/*************************** Utility Functions ********************************/
struct ahc_phase_table_entry*
ahc_lookup_phase_entry(int phase);
void ahc_compile_devinfo(struct ahc_devinfo *devinfo,
u_int our_id, u_int target,
u_int lun, char channel,
role_t role);
/************************** Transfer Negotiation ******************************/
struct ahc_syncrate* ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
const struct ahc_syncrate* ahc_find_syncrate(struct ahc_softc *ahc, u_int *period,
u_int *ppr_options, u_int maxsync);
u_int ahc_find_period(struct ahc_softc *ahc,
u_int scsirate, u_int maxsync);
void ahc_validate_offset(struct ahc_softc *ahc,
struct ahc_initiator_tinfo *tinfo,
struct ahc_syncrate *syncrate,
u_int *offset, int wide,
role_t role);
void ahc_validate_width(struct ahc_softc *ahc,
struct ahc_initiator_tinfo *tinfo,
u_int *bus_width,
role_t role);
/*
* Negotiation types. These are used to qualify if we should renegotiate
* even if our goal and current transport parameters are identical.
......@@ -1263,7 +1225,7 @@ void ahc_set_width(struct ahc_softc *ahc,
u_int width, u_int type, int paused);
void ahc_set_syncrate(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo,
struct ahc_syncrate *syncrate,
const struct ahc_syncrate *syncrate,
u_int period, u_int offset,
u_int ppr_options,
u_int type, int paused);
......@@ -1305,11 +1267,10 @@ extern uint32_t ahc_debug;
#define AHC_SHOW_MASKED_ERRORS 0x1000
#define AHC_DEBUG_SEQUENCER 0x2000
#endif
void ahc_print_scb(struct scb *scb);
void ahc_print_devinfo(struct ahc_softc *ahc,
struct ahc_devinfo *dev);
void ahc_dump_card_state(struct ahc_softc *ahc);
int ahc_print_register(ahc_reg_parse_entry_t *table,
int ahc_print_register(const ahc_reg_parse_entry_t *table,
u_int num_entries,
const char *name,
u_int address,
......
......@@ -238,6 +238,7 @@ register SXFRCTL2 {
register OPTIONMODE {
address 0x008
access_mode RW
count 2
field AUTORATEEN 0x80
field AUTOACKEN 0x40
field ATNMGMNTEN 0x20
......@@ -254,6 +255,7 @@ register TARGCRCCNT {
address 0x00a
size 2
access_mode RW
count 2
}
/*
......@@ -344,6 +346,7 @@ register SSTAT2 {
register SSTAT3 {
address 0x00e
access_mode RO
count 2
mask SCSICNT 0xf0
mask OFFCNT 0x0f
mask U2OFFCNT 0x7f
......@@ -367,6 +370,7 @@ register SCSIID_ULTRA2 {
register SIMODE0 {
address 0x010
access_mode RW
count 2
field ENSELDO 0x40
field ENSELDI 0x20
field ENSELINGO 0x10
......@@ -429,6 +433,7 @@ register SHADDR {
register SELTIMER {
address 0x018
access_mode RW
count 1
field STAGE6 0x20
field STAGE5 0x10
field STAGE4 0x08
......@@ -467,6 +472,7 @@ register TARGID {
address 0x01b
size 2
access_mode RW
count 14
}
/*
......@@ -480,6 +486,7 @@ register TARGID {
register SPIOCAP {
address 0x01b
access_mode RW
count 10
field SOFT1 0x80
field SOFT0 0x40
field SOFTCMDEN 0x20
......@@ -492,6 +499,7 @@ register SPIOCAP {
register BRDCTL {
address 0x01d
count 11
field BRDDAT7 0x80
field BRDDAT6 0x40
field BRDDAT5 0x20
......@@ -534,6 +542,7 @@ register BRDCTL {
*/
register SEECTL {
address 0x01e
count 11
field EXTARBACK 0x80
field EXTARBREQ 0x40
field SEEMS 0x20
......@@ -570,6 +579,7 @@ register SBLKCTL {
register SEQCTL {
address 0x060
access_mode RW
count 15
field PERRORDIS 0x80
field PAUSEDIS 0x40
field FAILDIS 0x20
......@@ -590,6 +600,7 @@ register SEQCTL {
register SEQRAM {
address 0x061
access_mode RW
count 2
}
/*
......@@ -604,6 +615,7 @@ register SEQADDR0 {
register SEQADDR1 {
address 0x063
access_mode RW
count 8
mask SEQADDR1_MASK 0x01
}
......@@ -649,6 +661,7 @@ register NONE {
register FLAGS {
address 0x06b
access_mode RO
count 18
field ZERO 0x02
field CARRY 0x01
}
......@@ -671,6 +684,7 @@ register FUNCTION1 {
register STACK {
address 0x06f
access_mode RO
count 5
}
const STACK_SIZE 4
......@@ -692,6 +706,7 @@ register BCTL {
register DSCOMMAND0 {
address 0x084
access_mode RW
count 7
field CACHETHEN 0x80 /* Cache Threshold enable */
field DPARCKEN 0x40 /* Data Parity Check Enable */
field MPARCKEN 0x20 /* Memory Parity Check Enable */
......@@ -717,6 +732,7 @@ register DSCOMMAND1 {
register BUSTIME {
address 0x085
access_mode RW
count 2
mask BOFF 0xf0
mask BON 0x0f
}
......@@ -727,6 +743,7 @@ register BUSTIME {
register BUSSPD {
address 0x086
access_mode RW
count 2
mask DFTHRSH 0xc0
mask STBOFF 0x38
mask STBON 0x07
......@@ -737,6 +754,7 @@ register BUSSPD {
/* aic7850/55/60/70/80/95 only */
register DSPCISTATUS {
address 0x086
count 4
mask DFTHRSH_100 0xc0
}
......@@ -758,6 +776,7 @@ const SEQ_MAILBOX_SHIFT 0
register HCNTRL {
address 0x087
access_mode RW
count 14
field POWRDN 0x40
field SWINT 0x10
field IRQMS 0x08
......@@ -869,6 +888,7 @@ register INTSTAT {
register ERROR {
address 0x092
access_mode RO
count 26
field CIOPARERR 0x80 /* Ultra2 only */
field PCIERRSTAT 0x40 /* PCI only */
field MPARERR 0x20 /* PCI only */
......@@ -885,6 +905,7 @@ register ERROR {
register CLRINT {
address 0x092
access_mode WO
count 24
field CLRPARERR 0x10 /* PCI only */
field CLRBRKADRINT 0x08
field CLRSCSIINT 0x04
......@@ -943,6 +964,7 @@ register DFDAT {
register SCBCNT {
address 0x09a
access_mode RW
count 1
field SCBAUTO 0x80
mask SCBCNT_MASK 0x1f
}
......@@ -954,6 +976,7 @@ register SCBCNT {
register QINFIFO {
address 0x09b
access_mode RW
count 12
}
/*
......@@ -972,11 +995,13 @@ register QINCNT {
register QOUTFIFO {
address 0x09d
access_mode WO
count 7
}
register CRCCONTROL1 {
address 0x09d
access_mode RW
count 3
field CRCONSEEN 0x80
field CRCVALCHKEN 0x40
field CRCENDCHKEN 0x20
......@@ -1013,6 +1038,7 @@ register SCSIPHASE {
register SFUNCT {
address 0x09f
access_mode RW
count 4
field ALT_MODE 0x80
}
......@@ -1095,6 +1121,7 @@ scb {
}
SCB_SCSIOFFSET {
size 1
count 1
}
SCB_NEXT {
size 1
......@@ -1118,6 +1145,7 @@ const SG_SIZEOF 0x08 /* sizeof(struct ahc_dma) */
register SEECTL_2840 {
address 0x0c0
access_mode RW
count 2
field CS_2840 0x04
field CK_2840 0x02
field DO_2840 0x01
......@@ -1126,6 +1154,7 @@ register SEECTL_2840 {
register STATUS_2840 {
address 0x0c1
access_mode RW
count 4
field EEPROM_TF 0x80
mask BIOS_SEL 0x60
mask ADSEL 0x1e
......@@ -1161,6 +1190,7 @@ register CCSGCTL {
register CCSCBCNT {
address 0xEF
count 1
}
register CCSCBCTL {
......@@ -1187,6 +1217,7 @@ register CCSCBRAM {
register SCBBADDR {
address 0x0F0
access_mode RW
count 3
}
register CCSCBPTR {
......@@ -1195,6 +1226,7 @@ register CCSCBPTR {
register HNSCB_QOFF {
address 0x0F4
count 4
}
register SNSCB_QOFF {
......@@ -1234,6 +1266,7 @@ register DFF_THRSH {
mask WR_DFTHRSH_85 0x50
mask WR_DFTHRSH_90 0x60
mask WR_DFTHRSH_MAX 0x70
count 4
}
register SG_CACHE_PRE {
......@@ -1287,6 +1320,7 @@ scratch_ram {
ULTRA_ENB {
alias CMDSIZE_TABLE
size 2
count 2
}
/*
* Bit vector of targets that have disconnection disabled as set by
......@@ -1296,6 +1330,7 @@ scratch_ram {
*/
DISC_DSB {
size 2
count 6
}
CMDSIZE_TABLE_TAIL {
size 4
......@@ -1323,6 +1358,7 @@ scratch_ram {
/* Parameters for DMA Logic */
DMAPARAMS {
size 1
count 12
field PRELOADEN 0x80
field WIDEODD 0x40
field SCSIEN 0x20
......@@ -1436,11 +1472,12 @@ scratch_ram {
KERNEL_TQINPOS {
size 1
}
TQINPOS {
TQINPOS {
size 1
}
ARG_1 {
size 1
count 1
mask SEND_MSG 0x80
mask SEND_SENSE 0x40
mask SEND_REJ 0x20
......@@ -1495,6 +1532,7 @@ scratch_ram {
size 1
field HA_274_EXTENDED_TRANS 0x01
alias INITIATOR_TAG
count 1
}
SEQ_FLAGS2 {
......@@ -1518,6 +1556,7 @@ scratch_ram {
*/
SCSICONF {
size 1
count 12
field TERM_ENB 0x80
field RESET_SCSI 0x40
field ENSPCHK 0x20
......@@ -1527,16 +1566,19 @@ scratch_ram {
INTDEF {
address 0x05c
size 1
count 1
field EDGE_TRIG 0x80
mask VECTOR 0x0f
}
HOSTCONF {
address 0x05d
size 1
count 1
}
HA_274_BIOSCTRL {
address 0x05f
size 1
count 1
mask BIOSMODE 0x30
mask BIOSDISABLED 0x30
field CHANNEL_B_PRIMARY 0x08
......@@ -1552,6 +1594,7 @@ scratch_ram {
*/
TARG_OFFSET {
size 16
count 1
}
}
......
......@@ -84,16 +84,16 @@ struct seeprom_cmd {
};
/* 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}};
static const struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
static const 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}};
static const struct seeprom_cmd seeprom_long_ewen = {11, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
static const 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}};
static const struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
static const struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
/*
* Wait for the SEERDY to go high; about 800 ns.
......@@ -108,7 +108,7 @@ static struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
* Send a START condition and the given command
*/
static void
send_seeprom_cmd(struct seeprom_descriptor *sd, struct seeprom_cmd *cmd)
send_seeprom_cmd(struct seeprom_descriptor *sd, const struct seeprom_cmd *cmd)
{
uint8_t temp;
int i = 0;
......@@ -227,7 +227,7 @@ int
ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
u_int start_addr, u_int count)
{
struct seeprom_cmd *ewen, *ewds;
const struct seeprom_cmd *ewen, *ewds;
uint16_t v;
uint8_t temp;
int i, k;
......
此差异已折叠。
......@@ -46,179 +46,13 @@
#define _AIC7XXX_INLINE_H_
/************************* Sequencer Execution Control ************************/
static __inline void ahc_pause_bug_fix(struct ahc_softc *ahc);
static __inline int ahc_is_paused(struct ahc_softc *ahc);
static __inline void ahc_pause(struct ahc_softc *ahc);
static __inline void ahc_unpause(struct ahc_softc *ahc);
/*
* Work around any chip bugs related to halting sequencer execution.
* On Ultra2 controllers, we must clear the CIOBUS stretch signal by
* reading a register that will set this signal and deassert it.
* Without this workaround, if the chip is paused, by an interrupt or
* manual pause while accessing scb ram, accesses to certain registers
* will hang the system (infinite pci retries).
*/
static __inline void
ahc_pause_bug_fix(struct ahc_softc *ahc)
{
if ((ahc->features & AHC_ULTRA2) != 0)
(void)ahc_inb(ahc, CCSCBCTL);
}
/*
* Determine whether the sequencer has halted code execution.
* Returns non-zero status if the sequencer is stopped.
*/
static __inline int
ahc_is_paused(struct ahc_softc *ahc)
{
return ((ahc_inb(ahc, HCNTRL) & PAUSE) != 0);
}
/*
* Request that the sequencer stop and wait, indefinitely, for it
* to stop. The sequencer will only acknowledge that it is paused
* once it has reached an instruction boundary and PAUSEDIS is
* cleared in the SEQCTL register. The sequencer may use PAUSEDIS
* for critical sections.
*/
static __inline void
ahc_pause(struct ahc_softc *ahc)
{
ahc_outb(ahc, HCNTRL, ahc->pause);
/*
* Since the sequencer can disable pausing in a critical section, we
* must loop until it actually stops.
*/
while (ahc_is_paused(ahc) == 0)
;
ahc_pause_bug_fix(ahc);
}
/*
* Allow the sequencer to continue program execution.
* We check here to ensure that no additional interrupt
* sources that would cause the sequencer to halt have been
* asserted. If, for example, a SCSI bus reset is detected
* while we are fielding a different, pausing, interrupt type,
* we don't want to release the sequencer before going back
* into our interrupt handler and dealing with this new
* condition.
*/
static __inline void
ahc_unpause(struct ahc_softc *ahc)
{
if ((ahc_inb(ahc, INTSTAT) & (SCSIINT | SEQINT | BRKADRINT)) == 0)
ahc_outb(ahc, HCNTRL, ahc->unpause);
}
/*********************** Untagged Transaction Routines ************************/
static __inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc);
static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc);
/*
* Block our completion routine from starting the next untagged
* transaction for this target or target lun.
*/
static __inline void
ahc_freeze_untagged_queues(struct ahc_softc *ahc)
{
if ((ahc->flags & AHC_SCB_BTT) == 0)
ahc->untagged_queue_lock++;
}
/*
* Allow the next untagged transaction for this target or target lun
* to be executed. We use a counting semaphore to allow the lock
* to be acquired recursively. Once the count drops to zero, the
* transaction queues will be run.
*/
static __inline void
ahc_release_untagged_queues(struct ahc_softc *ahc)
{
if ((ahc->flags & AHC_SCB_BTT) == 0) {
ahc->untagged_queue_lock--;
if (ahc->untagged_queue_lock == 0)
ahc_run_untagged_queues(ahc);
}
}
int ahc_is_paused(struct ahc_softc *ahc);
void ahc_pause(struct ahc_softc *ahc);
void ahc_unpause(struct ahc_softc *ahc);
/************************** Memory mapping routines ***************************/
static __inline struct ahc_dma_seg *
ahc_sg_bus_to_virt(struct scb *scb,
uint32_t sg_busaddr);
static __inline uint32_t
ahc_sg_virt_to_bus(struct scb *scb,
struct ahc_dma_seg *sg);
static __inline uint32_t
ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index);
static __inline void ahc_sync_scb(struct ahc_softc *ahc,
struct scb *scb, int op);
static __inline void ahc_sync_sglist(struct ahc_softc *ahc,
struct scb *scb, int op);
static __inline uint32_t
ahc_targetcmd_offset(struct ahc_softc *ahc,
u_int index);
static __inline struct ahc_dma_seg *
ahc_sg_bus_to_virt(struct scb *scb, uint32_t sg_busaddr)
{
int sg_index;
sg_index = (sg_busaddr - scb->sg_list_phys)/sizeof(struct ahc_dma_seg);
/* sg_list_phys points to entry 1, not 0 */
sg_index++;
return (&scb->sg_list[sg_index]);
}
static __inline uint32_t
ahc_sg_virt_to_bus(struct scb *scb, struct ahc_dma_seg *sg)
{
int sg_index;
/* sg_list_phys points to entry 1, not 0 */
sg_index = sg - &scb->sg_list[1];
return (scb->sg_list_phys + (sg_index * sizeof(*scb->sg_list)));
}
static __inline uint32_t
ahc_hscb_busaddr(struct ahc_softc *ahc, u_int index)
{
return (ahc->scb_data->hscb_busaddr
+ (sizeof(struct hardware_scb) * index));
}
static __inline void
ahc_sync_scb(struct ahc_softc *ahc, struct scb *scb, int op)
{
ahc_dmamap_sync(ahc, ahc->scb_data->hscb_dmat,
ahc->scb_data->hscb_dmamap,
/*offset*/(scb->hscb - ahc->hscbs) * sizeof(*scb->hscb),
/*len*/sizeof(*scb->hscb), op);
}
static __inline void
ahc_sync_sglist(struct ahc_softc *ahc, struct scb *scb, int op)
{
if (scb->sg_count == 0)
return;
ahc_dmamap_sync(ahc, ahc->scb_data->sg_dmat, scb->sg_map->sg_dmamap,
/*offset*/(scb->sg_list - scb->sg_map->sg_vaddr)
* sizeof(struct ahc_dma_seg),
/*len*/sizeof(struct ahc_dma_seg) * scb->sg_count, op);
}
static __inline uint32_t
ahc_targetcmd_offset(struct ahc_softc *ahc, u_int index)
{
return (((uint8_t *)&ahc->targetcmds[index]) - ahc->qoutfifo);
}
void ahc_sync_sglist(struct ahc_softc *ahc,
struct scb *scb, int op);
/******************************** Debugging ***********************************/
static __inline char *ahc_name(struct ahc_softc *ahc);
......@@ -231,420 +65,34 @@ ahc_name(struct ahc_softc *ahc)
/*********************** Miscellaneous Support Functions ***********************/
static __inline void ahc_update_residual(struct ahc_softc *ahc,
struct scb *scb);
static __inline struct ahc_initiator_tinfo *
ahc_fetch_transinfo(struct ahc_softc *ahc,
char channel, u_int our_id,
u_int remote_id,
struct ahc_tmode_tstate **tstate);
static __inline uint16_t
ahc_inw(struct ahc_softc *ahc, u_int port);
static __inline void ahc_outw(struct ahc_softc *ahc, u_int port,
u_int value);
static __inline uint32_t
ahc_inl(struct ahc_softc *ahc, u_int port);
static __inline void ahc_outl(struct ahc_softc *ahc, u_int port,
uint32_t value);
static __inline uint64_t
ahc_inq(struct ahc_softc *ahc, u_int port);
static __inline void ahc_outq(struct ahc_softc *ahc, u_int port,
uint64_t value);
static __inline struct scb*
ahc_get_scb(struct ahc_softc *ahc);
static __inline void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
static __inline void ahc_swap_with_next_hscb(struct ahc_softc *ahc,
struct scb *scb);
static __inline void ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb);
static __inline struct scsi_sense_data *
ahc_get_sense_buf(struct ahc_softc *ahc,
struct scb *scb);
static __inline uint32_t
ahc_get_sense_bufaddr(struct ahc_softc *ahc,
struct scb *scb);
/*
* Determine whether the sequencer reported a residual
* for this SCB/transaction.
*/
static __inline void
ahc_update_residual(struct ahc_softc *ahc, struct scb *scb)
{
uint32_t sgptr;
sgptr = ahc_le32toh(scb->hscb->sgptr);
if ((sgptr & SG_RESID_VALID) != 0)
ahc_calc_residual(ahc, scb);
}
/*
* Return pointers to the transfer negotiation information
* for the specified our_id/remote_id pair.
*/
static __inline struct ahc_initiator_tinfo *
ahc_fetch_transinfo(struct ahc_softc *ahc, char channel, u_int our_id,
u_int remote_id, struct ahc_tmode_tstate **tstate)
{
/*
* Transfer data structures are stored from the perspective
* of the target role. Since the parameters for a connection
* in the initiator role to a given target are the same as
* when the roles are reversed, we pretend we are the target.
*/
if (channel == 'B')
our_id += 8;
*tstate = ahc->enabled_targets[our_id];
return (&(*tstate)->transinfo[remote_id]);
}
static __inline uint16_t
ahc_inw(struct ahc_softc *ahc, u_int port)
{
uint16_t r = ahc_inb(ahc, port+1) << 8;
return r | ahc_inb(ahc, port);
}
static __inline void
ahc_outw(struct ahc_softc *ahc, u_int port, u_int value)
{
ahc_outb(ahc, port, value & 0xFF);
ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
}
static __inline uint32_t
ahc_inl(struct ahc_softc *ahc, u_int port)
{
return ((ahc_inb(ahc, port))
| (ahc_inb(ahc, port+1) << 8)
| (ahc_inb(ahc, port+2) << 16)
| (ahc_inb(ahc, port+3) << 24));
}
static __inline void
ahc_outl(struct ahc_softc *ahc, u_int port, uint32_t value)
{
ahc_outb(ahc, port, (value) & 0xFF);
ahc_outb(ahc, port+1, ((value) >> 8) & 0xFF);
ahc_outb(ahc, port+2, ((value) >> 16) & 0xFF);
ahc_outb(ahc, port+3, ((value) >> 24) & 0xFF);
}
static __inline uint64_t
ahc_inq(struct ahc_softc *ahc, u_int port)
{
return ((ahc_inb(ahc, port))
| (ahc_inb(ahc, port+1) << 8)
| (ahc_inb(ahc, port+2) << 16)
| (ahc_inb(ahc, port+3) << 24)
| (((uint64_t)ahc_inb(ahc, port+4)) << 32)
| (((uint64_t)ahc_inb(ahc, port+5)) << 40)
| (((uint64_t)ahc_inb(ahc, port+6)) << 48)
| (((uint64_t)ahc_inb(ahc, port+7)) << 56));
}
static __inline void
ahc_outq(struct ahc_softc *ahc, u_int port, uint64_t value)
{
ahc_outb(ahc, port, value & 0xFF);
ahc_outb(ahc, port+1, (value >> 8) & 0xFF);
ahc_outb(ahc, port+2, (value >> 16) & 0xFF);
ahc_outb(ahc, port+3, (value >> 24) & 0xFF);
ahc_outb(ahc, port+4, (value >> 32) & 0xFF);
ahc_outb(ahc, port+5, (value >> 40) & 0xFF);
ahc_outb(ahc, port+6, (value >> 48) & 0xFF);
ahc_outb(ahc, port+7, (value >> 56) & 0xFF);
}
/*
* Get a free scb. If there are none, see if we can allocate a new SCB.
*/
static __inline struct scb *
ahc_get_scb(struct ahc_softc *ahc)
{
struct scb *scb;
if ((scb = SLIST_FIRST(&ahc->scb_data->free_scbs)) == NULL) {
ahc_alloc_scbs(ahc);
scb = SLIST_FIRST(&ahc->scb_data->free_scbs);
if (scb == NULL)
return (NULL);
}
SLIST_REMOVE_HEAD(&ahc->scb_data->free_scbs, links.sle);
return (scb);
}
/*
* Return an SCB resource to the free list.
*/
static __inline void
ahc_free_scb(struct ahc_softc *ahc, struct scb *scb)
{
struct hardware_scb *hscb;
hscb = scb->hscb;
/* Clean up for the next user */
ahc->scb_data->scbindex[hscb->tag] = NULL;
scb->flags = SCB_FREE;
hscb->control = 0;
SLIST_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links.sle);
/* Notify the OSM that a resource is now available. */
ahc_platform_scb_free(ahc, scb);
}
static __inline struct scb *
ahc_lookup_scb(struct ahc_softc *ahc, u_int tag)
{
struct scb* scb;
scb = ahc->scb_data->scbindex[tag];
if (scb != NULL)
ahc_sync_scb(ahc, scb,
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
return (scb);
}
static __inline void
ahc_swap_with_next_hscb(struct ahc_softc *ahc, struct scb *scb)
{
struct hardware_scb *q_hscb;
u_int saved_tag;
/*
* Our queuing method is a bit tricky. The card
* knows in advance which HSCB to download, and we
* can't disappoint it. To achieve this, the next
* SCB to download is saved off in ahc->next_queued_scb.
* When we are called to queue "an arbitrary scb",
* we copy the contents of the incoming HSCB to the one
* the sequencer knows about, swap HSCB pointers and
* finally assign the SCB to the tag indexed location
* in the scb_array. This makes sure that we can still
* locate the correct SCB by SCB_TAG.
*/
q_hscb = ahc->next_queued_scb->hscb;
saved_tag = q_hscb->tag;
memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb));
if ((scb->flags & SCB_CDB32_PTR) != 0) {
q_hscb->shared_data.cdb_ptr =
ahc_htole32(ahc_hscb_busaddr(ahc, q_hscb->tag)
+ offsetof(struct hardware_scb, cdb32));
}
q_hscb->tag = saved_tag;
q_hscb->next = scb->hscb->tag;
/* Now swap HSCB pointers. */
ahc->next_queued_scb->hscb = scb->hscb;
scb->hscb = q_hscb;
/* Now define the mapping from tag to SCB in the scbindex */
ahc->scb_data->scbindex[scb->hscb->tag] = scb;
}
/*
* Tell the sequencer about a new transaction to execute.
*/
static __inline void
ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb)
{
ahc_swap_with_next_hscb(ahc, scb);
if (scb->hscb->tag == SCB_LIST_NULL
|| scb->hscb->next == SCB_LIST_NULL)
panic("Attempt to queue invalid SCB tag %x:%x\n",
scb->hscb->tag, scb->hscb->next);
/*
* Setup data "oddness".
*/
scb->hscb->lun &= LID;
if (ahc_get_transfer_length(scb) & 0x1)
scb->hscb->lun |= SCB_XFERLEN_ODD;
/*
* Keep a history of SCBs we've downloaded in the qinfifo.
*/
ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag;
/*
* Make sure our data is consistent from the
* perspective of the adapter.
*/
ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
/* Tell the adapter about the newly queued SCB */
if ((ahc->features & AHC_QUEUE_REGS) != 0) {
ahc_outb(ahc, HNSCB_QOFF, ahc->qinfifonext);
} else {
if ((ahc->features & AHC_AUTOPAUSE) == 0)
ahc_pause(ahc);
ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext);
if ((ahc->features & AHC_AUTOPAUSE) == 0)
ahc_unpause(ahc);
}
}
static __inline struct scsi_sense_data *
ahc_get_sense_buf(struct ahc_softc *ahc, struct scb *scb)
{
int offset;
offset = scb - ahc->scb_data->scbarray;
return (&ahc->scb_data->sense[offset]);
}
static __inline uint32_t
ahc_get_sense_bufaddr(struct ahc_softc *ahc, struct scb *scb)
{
int offset;
offset = scb - ahc->scb_data->scbarray;
return (ahc->scb_data->sense_busaddr
+ (offset * sizeof(struct scsi_sense_data)));
}
struct ahc_initiator_tinfo *
ahc_fetch_transinfo(struct ahc_softc *ahc,
char channel, u_int our_id,
u_int remote_id,
struct ahc_tmode_tstate **tstate);
uint16_t
ahc_inw(struct ahc_softc *ahc, u_int port);
void ahc_outw(struct ahc_softc *ahc, u_int port,
u_int value);
uint32_t
ahc_inl(struct ahc_softc *ahc, u_int port);
void ahc_outl(struct ahc_softc *ahc, u_int port,
uint32_t value);
uint64_t
ahc_inq(struct ahc_softc *ahc, u_int port);
void ahc_outq(struct ahc_softc *ahc, u_int port,
uint64_t value);
struct scb*
ahc_get_scb(struct ahc_softc *ahc);
void ahc_free_scb(struct ahc_softc *ahc, struct scb *scb);
struct scb *
ahc_lookup_scb(struct ahc_softc *ahc, u_int tag);
void ahc_queue_scb(struct ahc_softc *ahc, struct scb *scb);
struct scsi_sense_data *
ahc_get_sense_buf(struct ahc_softc *ahc,
struct scb *scb);
/************************** Interrupt Processing ******************************/
static __inline void ahc_sync_qoutfifo(struct ahc_softc *ahc, int op);
static __inline void ahc_sync_tqinfifo(struct ahc_softc *ahc, int op);
static __inline u_int ahc_check_cmdcmpltqueues(struct ahc_softc *ahc);
static __inline int ahc_intr(struct ahc_softc *ahc);
static __inline void
ahc_sync_qoutfifo(struct ahc_softc *ahc, int op)
{
ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
/*offset*/0, /*len*/256, op);
}
static __inline void
ahc_sync_tqinfifo(struct ahc_softc *ahc, int op)
{
#ifdef AHC_TARGET_MODE
if ((ahc->flags & AHC_TARGETROLE) != 0) {
ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
ahc->shared_data_dmamap,
ahc_targetcmd_offset(ahc, 0),
sizeof(struct target_cmd) * AHC_TMODE_CMDS,
op);
}
#endif
}
/*
* See if the firmware has posted any completed commands
* into our in-core command complete fifos.
*/
#define AHC_RUN_QOUTFIFO 0x1
#define AHC_RUN_TQINFIFO 0x2
static __inline u_int
ahc_check_cmdcmpltqueues(struct ahc_softc *ahc)
{
u_int retval;
retval = 0;
ahc_dmamap_sync(ahc, ahc->shared_data_dmat, ahc->shared_data_dmamap,
/*offset*/ahc->qoutfifonext, /*len*/1,
BUS_DMASYNC_POSTREAD);
if (ahc->qoutfifo[ahc->qoutfifonext] != SCB_LIST_NULL)
retval |= AHC_RUN_QOUTFIFO;
#ifdef AHC_TARGET_MODE
if ((ahc->flags & AHC_TARGETROLE) != 0
&& (ahc->flags & AHC_TQINFIFO_BLOCKED) == 0) {
ahc_dmamap_sync(ahc, ahc->shared_data_dmat,
ahc->shared_data_dmamap,
ahc_targetcmd_offset(ahc, ahc->tqinfifofnext),
/*len*/sizeof(struct target_cmd),
BUS_DMASYNC_POSTREAD);
if (ahc->targetcmds[ahc->tqinfifonext].cmd_valid != 0)
retval |= AHC_RUN_TQINFIFO;
}
#endif
return (retval);
}
/*
* Catch an interrupt from the adapter
*/
static __inline int
ahc_intr(struct ahc_softc *ahc)
{
u_int intstat;
if ((ahc->pause & INTEN) == 0) {
/*
* Our interrupt is not enabled on the chip
* and may be disabled for re-entrancy reasons,
* so just return. This is likely just a shared
* interrupt.
*/
return (0);
}
/*
* Instead of directly reading the interrupt status register,
* infer the cause of the interrupt by checking our in-core
* completion queues. This avoids a costly PCI bus read in
* most cases.
*/
if ((ahc->flags & (AHC_ALL_INTERRUPTS|AHC_EDGE_INTERRUPT)) == 0
&& (ahc_check_cmdcmpltqueues(ahc) != 0))
intstat = CMDCMPLT;
else {
intstat = ahc_inb(ahc, INTSTAT);
}
if ((intstat & INT_PEND) == 0) {
#if AHC_PCI_CONFIG > 0
if (ahc->unsolicited_ints > 500) {
ahc->unsolicited_ints = 0;
if ((ahc->chip & AHC_PCI) != 0
&& (ahc_inb(ahc, ERROR) & PCIERRSTAT) != 0)
ahc->bus_intr(ahc);
}
#endif
ahc->unsolicited_ints++;
return (0);
}
ahc->unsolicited_ints = 0;
if (intstat & CMDCMPLT) {
ahc_outb(ahc, CLRINT, CLRCMDINT);
/*
* Ensure that the chip sees that we've cleared
* this interrupt before we walk the output fifo.
* Otherwise, we may, due to posted bus writes,
* clear the interrupt after we finish the scan,
* and after the sequencer has added new entries
* and asserted the interrupt again.
*/
ahc_flush_device_writes(ahc);
ahc_run_qoutfifo(ahc);
#ifdef AHC_TARGET_MODE
if ((ahc->flags & AHC_TARGETROLE) != 0)
ahc_run_tqinfifo(ahc, /*paused*/FALSE);
#endif
}
/*
* Handle statuses that may invalidate our cached
* copy of INTSTAT separately.
*/
if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) {
/* Hot eject. Do nothing */
} else if (intstat & BRKADRINT) {
ahc_handle_brkadrint(ahc);
} else if ((intstat & (SEQINT|SCSIINT)) != 0) {
ahc_pause_bug_fix(ahc);
if ((intstat & SEQINT) != 0)
ahc_handle_seqint(ahc, intstat);
if ((intstat & SCSIINT) != 0)
ahc_handle_scsiint(ahc, intstat);
}
return (1);
}
int ahc_intr(struct ahc_softc *ahc);
#endif /* _AIC7XXX_INLINE_H_ */
此差异已折叠。
此差异已折叠。
......@@ -168,8 +168,7 @@ static ahc_device_setup_t ahc_aha394XX_setup;
static ahc_device_setup_t ahc_aha494XX_setup;
static ahc_device_setup_t ahc_aha398XX_setup;
static struct ahc_pci_identity ahc_pci_ident_table [] =
{
static const struct ahc_pci_identity ahc_pci_ident_table[] = {
/* aic7850 based controllers */
{
ID_AHA_2902_04_10_15_20C_30C,
......@@ -668,7 +667,7 @@ ahc_9005_subdevinfo_valid(uint16_t device, uint16_t vendor,
return (result);
}
struct ahc_pci_identity *
const struct ahc_pci_identity *
ahc_find_pci_device(ahc_dev_softc_t pci)
{
uint64_t full_id;
......@@ -676,7 +675,7 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
uint16_t vendor;
uint16_t subdevice;
uint16_t subvendor;
struct ahc_pci_identity *entry;
const struct ahc_pci_identity *entry;
u_int i;
vendor = ahc_pci_read_config(pci, PCIR_DEVVENDOR, /*bytes*/2);
......@@ -710,7 +709,7 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
}
int
ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
{
u_int command;
u_int our_id;
......
......@@ -58,7 +58,7 @@ static int ahc_proc_write_seeprom(struct ahc_softc *ahc,
* Table of syncrates that don't follow the "divisible by 4"
* rule. This table will be expanded in future SCSI specs.
*/
static struct {
static const struct {
u_int period_factor;
u_int period; /* in 100ths of ns */
} scsi_syncrates[] = {
......@@ -137,7 +137,7 @@ copy_info(struct info_str *info, char *fmt, ...)
return (len);
}
void
static void
ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo)
{
u_int speed;
......
......@@ -5,7 +5,7 @@
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#58 $
* $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#40 $
*/
static uint8_t seqprog[] = {
static const uint8_t seqprog[] = {
0xb2, 0x00, 0x00, 0x08,
0xf7, 0x11, 0x22, 0x08,
0x00, 0x65, 0xee, 0x59,
......@@ -1081,7 +1081,7 @@ ahc_patch0_func(struct ahc_softc *ahc)
return (0);
}
static struct patch {
static const struct patch {
ahc_patch_func_t *patch_func;
uint32_t begin :10,
skip_instr :10,
......@@ -1291,7 +1291,7 @@ static struct patch {
{ ahc_patch4_func, 865, 12, 1 }
};
static struct cs {
static const struct cs {
uint16_t begin;
uint16_t end;
} critical_sections[] = {
......
......@@ -362,7 +362,7 @@ output_code()
" *\n"
"%s */\n", versions);
fprintf(ofile, "static uint8_t seqprog[] = {\n");
fprintf(ofile, "static const uint8_t seqprog[] = {\n");
for (cur_instr = STAILQ_FIRST(&seq_program);
cur_instr != NULL;
cur_instr = STAILQ_NEXT(cur_instr, links)) {
......@@ -415,7 +415,7 @@ output_code()
}
fprintf(ofile,
"static struct patch {\n"
"static const struct patch {\n"
" %spatch_func_t *patch_func;\n"
" uint32_t begin :10,\n"
" skip_instr :10,\n"
......@@ -435,7 +435,7 @@ output_code()
fprintf(ofile, "\n};\n\n");
fprintf(ofile,
"static struct cs {\n"
"static const struct cs {\n"
" uint16_t begin;\n"
" uint16_t end;\n"
"} critical_sections[] = {\n");
......
......@@ -128,6 +128,7 @@ typedef struct expression_info {
typedef struct symbol {
char *name;
symtype type;
int count;
union {
struct reg_info *rinfo;
struct field_info *finfo;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -151,10 +151,6 @@ qla2x00_verify_checksum(scsi_qla_host_t *, uint32_t);
extern int
qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
extern int
qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t,
uint32_t);
extern int
qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册