Commit 62cc7f66 authored by James Bottomley's avatar James Bottomley Committed by Christoph Hellwig

MPT Fusion driver 3.01.10 update

From: "Moore, Eric Dean" <Emoore@lsil.com>

This driver incorporates the patches from Christoph Hellwig
and Masao Fukuchi.

Changelog of this release:

* Patch provided by  Masao Fukuchi [fukuchi.masao@jp.fujitsu.com]
 - mptctl updates for hot plug

* Patch provided by Christoph Hellwig [hch@infradead.org]
 - mptlan updates for hot plug
 - remove CONFIG_LBD ifdefs from fusion { mptscsih.c}
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 40f816ba
......@@ -1337,7 +1337,6 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
ioc->name, __irq_itoa(pdev->irq));
#endif
Q_DEL_ITEM(ioc);
list_del(&ioc->list);
iounmap(mem);
kfree(ioc);
......@@ -1369,7 +1368,6 @@ mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
": WARNING - %s did not initialize properly! (%d)\n",
ioc->name, r);
Q_DEL_ITEM(ioc);
list_del(&ioc->list);
free_irq(ioc->pci_irq, ioc);
iounmap(mem);
......
......@@ -85,8 +85,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.01.09"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.09"
#define MPT_LINUX_VERSION_COMMON "3.01.10"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.10"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
......@@ -523,6 +523,7 @@ typedef struct _MPT_IOCTL {
u8 target; /* target for reset */
void *tmPtr;
struct timer_list TMtimer; /* timer function for this adapter */
struct semaphore sem_ioc;
} MPT_IOCTL;
/*
......@@ -676,6 +677,7 @@ typedef struct _MPT_ADAPTER
u8 reload_fw; /* Force a FW Reload on next reset */
u8 pad1[5];
struct list_head list;
struct net_device *netdev;
} MPT_ADAPTER;
......
......@@ -111,7 +111,6 @@ MODULE_LICENSE("GPL");
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int mptctl_id = -1;
static struct semaphore mptctl_syscall_sem_ioc[MPT_MAX_ADAPTERS];
static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
......@@ -140,6 +139,9 @@ static int mptctl_do_reset(unsigned long arg);
static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
static int mptctl_hp_targetinfo(unsigned long arg);
static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
static void mptctl_remove(struct pci_dev *);
/*
* Private function calls.
*/
......@@ -208,10 +210,10 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
}
if (nonblock) {
if (down_trylock(&mptctl_syscall_sem_ioc[ioc->id]))
if (down_trylock(&ioc->ioctl->sem_ioc))
rc = -EAGAIN;
} else {
if (down_interruptible(&mptctl_syscall_sem_ioc[ioc->id]))
if (down_interruptible(&ioc->ioctl->sem_ioc))
rc = -ERESTARTSYS;
}
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down return %d\n", rc));
......@@ -630,8 +632,7 @@ mptctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
else
ret = -EINVAL;
up(&mptctl_syscall_sem_ioc[iocp->id]);
up(&iocp->ioctl->sem_ioc);
return ret;
}
......@@ -2738,7 +2739,7 @@ compat_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
up(&mptctl_syscall_sem_ioc[iocp->id]);
up(&iocp->ioctl->sem_ioc);
return ret;
}
......@@ -2792,55 +2793,91 @@ compat_mpt_command(unsigned int fd, unsigned int cmd,
*/
ret = mptctl_do_mpt_command (karg, &uarg->MF);
up(&mptctl_syscall_sem_ioc[iocp->id]);
up(&iocp->ioctl->sem_ioc);
return ret;
}
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init mptctl_init(void)
/*
* mptctl_probe - Installs ioctl devices per bus.
* @pdev: Pointer to pci_dev structure
*
* Returns 0 for success, non-zero for failure.
*
*/
static int
mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int err;
int i;
int where = 1;
int sz;
u8 *mem;
MPT_ADAPTER *ioc = NULL;
int iocnum;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
show_mptmod_ver(my_NAME, my_VERSION);
/*
* Allocate and inite a MPT_IOCTL structure
*/
sz = sizeof (MPT_IOCTL);
mem = kmalloc(sz, GFP_KERNEL);
if (mem == NULL) {
err = -ENOMEM;
goto out_fail;
}
for (i=0; i<MPT_MAX_ADAPTERS; i++) {
sema_init(&mptctl_syscall_sem_ioc[i], 1);
memset(mem, 0, sz);
ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc;
init_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->timer.function = mptctl_timer_expired;
init_timer (&ioc->ioctl->TMtimer);
ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->TMtimer.function = mptctl_timer_expired;
sema_init(&ioc->ioctl->sem_ioc, 1);
return 0;
ioc = NULL;
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
/* This adapter instance is found.
* Allocate and inite a MPT_IOCTL structure
*/
sz = sizeof (MPT_IOCTL);
mem = kmalloc(sz, GFP_KERNEL);
if (mem == NULL) {
err = -ENOMEM;
goto out_fail;
}
out_fail:
memset(mem, 0, sz);
ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc;
init_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->timer.function = mptctl_timer_expired;
init_timer (&ioc->ioctl->TMtimer);
ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->TMtimer.function = mptctl_timer_expired;
}
mptctl_remove(pdev);
return err;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptctl_remove - Removed ioctl devices
* @pdev: Pointer to pci_dev structure
*
*
*/
static void
mptctl_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
kfree ( ioc->ioctl );
}
static struct mpt_pci_driver mptctl_driver = {
.probe = mptctl_probe,
.remove = mptctl_remove,
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int __init mptctl_init(void)
{
int err;
int where = 1;
show_mptmod_ver(my_NAME, my_VERSION);
if(mpt_device_driver_register(&mptctl_driver,
MPTCTL_DRIVER) != 0 ) {
dprintk((KERN_INFO MYNAM
": failed to register dd callbacks\n"));
}
#ifdef CONFIG_COMPAT
......@@ -2922,29 +2959,14 @@ int __init mptctl_init(void)
unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif
for (i=0; i<MPT_MAX_ADAPTERS; i++) {
ioc = NULL;
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
if (ioc->ioctl) {
kfree ( ioc->ioctl );
ioc->ioctl = NULL;
}
}
}
mpt_device_driver_deregister(MPTCTL_DRIVER);
return err;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
void mptctl_exit(void)
{
int i;
MPT_ADAPTER *ioc;
int iocnum;
misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
......@@ -2957,6 +2979,8 @@ void mptctl_exit(void)
mpt_deregister(mptctl_id);
printk(KERN_INFO MYNAM ": Deregistered from Fusion MPT base driver\n");
mpt_device_driver_deregister(MPTCTL_DRIVER);
#ifdef CONFIG_COMPAT
unregister_ioctl32_conversion(MPTIOCINFO);
unregister_ioctl32_conversion(MPTIOCINFO1);
......@@ -2973,20 +2997,6 @@ void mptctl_exit(void)
unregister_ioctl32_conversion(HP_GETTARGETINFO);
#endif
/* Free allocated memory */
for (i=0; i<MPT_MAX_ADAPTERS; i++) {
ioc = NULL;
if (((iocnum = mpt_verify_adapter(i, &ioc)) < 0) ||
(ioc == NULL)) {
continue;
}
else {
if (ioc->ioctl) {
kfree ( ioc->ioctl );
ioc->ioctl = NULL;
}
}
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......
......@@ -177,11 +177,9 @@ static int LanCtx = -1;
static u32 max_buckets_out = 127;
static u32 tx_max_out_p = 127 - 16;
static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
#ifdef QLOGIC_NAA_WORKAROUND
static struct NAA_Hosed *mpt_bad_naa = NULL;
rwlock_t bad_naa_lock;
rwlock_t bad_naa_lock = RW_LOCK_UNLOCKED;
#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
......@@ -203,7 +201,7 @@ extern int mpt_lan_index;
static int
lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
{
struct net_device *dev = mpt_landev[ioc->id];
struct net_device *dev = ioc->netdev;
int FreeReqFrame = 0;
dioprintk((KERN_INFO MYNAM ": %s/%s: Got reply.\n",
......@@ -336,7 +334,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
struct net_device *dev = mpt_landev[ioc->id];
struct net_device *dev = ioc->netdev;
struct mpt_lan_priv *priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
......@@ -1451,20 +1449,74 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
return dev;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int __init mpt_lan_init (void)
static int
mptlan_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net_device *dev;
MPT_ADAPTER *p;
int i, j;
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct net_device *dev;
int i;
for (i = 0; i < ioc->facts.NumberOfPorts; i++) {
printk(KERN_INFO MYNAM ": %s: PortNum=%x, "
"ProtocolFlags=%02Xh (%c%c%c%c)\n",
ioc->name, ioc->pfacts[i].PortNumber,
ioc->pfacts[i].ProtocolFlags,
MPT_PROTOCOL_FLAGS_c_c_c_c(
ioc->pfacts[i].ProtocolFlags));
if (!(ioc->pfacts[i].ProtocolFlags &
MPI_PORTFACTS_PROTOCOL_LAN)) {
printk(KERN_INFO MYNAM ": %s: Hmmm... LAN protocol "
"seems to be disabled on this adapter port!\n",
ioc->name);
continue;
}
show_mptmod_ver(LANAME, LANVER);
dev = mpt_register_lan_device(ioc, i);
if (!dev) {
printk(KERN_ERR MYNAM ": %s: Unable to register "
"port%d as a LAN device\n", ioc->name,
ioc->pfacts[i].PortNumber);
continue;
}
printk(KERN_INFO MYNAM ": %s: Fusion MPT LAN device "
"registered as '%s'\n", ioc->name, dev->name);
printk(KERN_INFO MYNAM ": %s/%s: "
"LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
IOC_AND_NETDEV_NAMES_s_s(dev),
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5]);
ioc->netdev = dev;
#ifdef QLOGIC_NAA_WORKAROUND
/* Init the global r/w lock for the bad_naa list. We want to do this
before any boards are initialized and may be used. */
rwlock_init(&bad_naa_lock);
#endif
return 0;
}
return -ENODEV;
}
static void
mptlan_remove(struct pci_dev *pdev)
{
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
struct net_device *dev = ioc->netdev;
if(dev != NULL) {
unregister_netdev(dev);
free_netdev(dev);
}
}
static struct mpt_pci_driver mptlan_driver = {
.probe = mptlan_probe,
.remove = mptlan_remove,
};
static int __init mpt_lan_init (void)
{
show_mptmod_ver(LANAME, LANVER);
if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
......@@ -1476,88 +1528,32 @@ static int __init mpt_lan_init (void)
dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
} else {
if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset)) {
printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
"handler with mptbase! The world is at an end! "
"Everything is fading to black! Goodbye.\n");
return -EBUSY;
}
for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
mpt_landev[j] = NULL;
}
list_for_each_entry(p, &ioc_list, list) {
for (i = 0; i < p->facts.NumberOfPorts; i++) {
printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
p->name,
p->pfacts[i].PortNumber,
p->pfacts[i].ProtocolFlags,
MPT_PROTOCOL_FLAGS_c_c_c_c(p->pfacts[i].ProtocolFlags));
if (!(p->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
p->name);
continue;
}
dev = mpt_register_lan_device (p, i);
if (!dev) {
printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
p->name,
p->pfacts[i].PortNumber);
}
printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
p->name, dev->name);
printk (KERN_INFO MYNAM ": %s/%s: LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
IOC_AND_NETDEV_NAMES_s_s(dev),
dev->dev_addr[0], dev->dev_addr[1],
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5]);
// printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n",
// IOC_AND_NETDEV_NAMES_s_s(dev),
// NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
j = p->id;
mpt_landev[j] = dev;
dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
dev, j, mpt_landev[j]));
}
}
dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
if (mpt_device_driver_register(&mptlan_driver, MPTLAN_DRIVER))
dprintk((KERN_INFO MYNAM ": failed to register dd callbacks\n"));
return 0;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void __exit mpt_lan_exit(void)
{
int i;
mpt_device_driver_deregister(MPTLAN_DRIVER);
mpt_reset_deregister(LanCtx);
for (i = 0; mpt_landev[i] != NULL; i++) {
struct net_device *dev = mpt_landev[i];
printk (KERN_INFO ": %s/%s: Fusion MPT LAN device unregistered\n",
IOC_AND_NETDEV_NAMES_s_s(dev));
unregister_netdev(dev);
free_netdev(dev);
mpt_landev[i] = NULL;
}
if (LanCtx >= 0) {
mpt_deregister(LanCtx);
LanCtx = -1;
mpt_lan_index = 0;
}
/* deregister any send/receive handler structs. I2Oism? */
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
module_init(mpt_lan_init);
module_exit(mpt_lan_exit);
......
......@@ -3058,19 +3058,14 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
int heads;
int sectors;
sector_t cylinders;
#ifdef CONFIG_LBD
ulong dummy;
#endif
heads = 64;
sectors = 32;
#ifdef CONFIG_LBD
dummy = heads * sectors;
cylinders = capacity;
sector_div(cylinders,dummy);
#else
cylinders = (ulong)capacity / (heads * sectors);
#endif
/*
* Handle extended translation size for logical drives
......@@ -3079,13 +3074,9 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
if ((ulong)capacity >= 0x200000) {
heads = 255;
sectors = 63;
#ifdef CONFIG_LBD
dummy = heads * sectors;
cylinders = capacity;
sector_div(cylinders,dummy);
#else
cylinders = (ulong)capacity / (heads * sectors);
#endif
}
/* return result */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment