Commit 7d6322b4 authored by Linus Torvalds's avatar Linus Torvalds

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

parents d6b9acc0 51c928c3
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
Remove un-needed eh_abort handler. Remove un-needed eh_abort handler.
Add support for embedded firmware error strings. Add support for embedded firmware error strings.
2.26.02.003 - Correctly handle single sgl's with use_sg=1. 2.26.02.003 - Correctly handle single sgl's with use_sg=1.
2.26.02.004 - Add support for 9550SX controllers.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -82,7 +83,7 @@ ...@@ -82,7 +83,7 @@
#include "3w-9xxx.h" #include "3w-9xxx.h"
/* Globals */ /* Globals */
#define TW_DRIVER_VERSION "2.26.02.003" #define TW_DRIVER_VERSION "2.26.02.004"
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count; static unsigned int twa_device_extension_count;
static int twa_major = -1; static int twa_major = -1;
...@@ -892,11 +893,6 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value) ...@@ -892,11 +893,6 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev)); writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
} }
if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
}
if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) { if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
if (tw_dev->reset_print == 0) { if (tw_dev->reset_print == 0) {
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing"); TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
...@@ -930,6 +926,36 @@ static int twa_empty_response_queue(TW_Device_Extension *tw_dev) ...@@ -930,6 +926,36 @@ static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
return retval; return retval;
} /* End twa_empty_response_queue() */ } /* End twa_empty_response_queue() */
/* This function will clear the pchip/response queue on 9550SX */
static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
{
u32 status_reg_value, response_que_value;
int count = 0, retval = 1;
if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) {
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
if ((response_que_value & TW_9550SX_DRAIN_COMPLETED) == TW_9550SX_DRAIN_COMPLETED) {
/* P-chip settle time */
msleep(500);
retval = 0;
goto out;
}
status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
count++;
}
if (count == TW_MAX_RESPONSE_DRAIN)
goto out;
retval = 0;
} else
retval = 0;
out:
return retval;
} /* End twa_empty_response_queue_large() */
/* This function passes sense keys from firmware to scsi layer */ /* This function passes sense keys from firmware to scsi layer */
static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host) static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
{ {
...@@ -1613,8 +1639,16 @@ static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset) ...@@ -1613,8 +1639,16 @@ static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset; int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
while (tries < TW_MAX_RESET_TRIES) { while (tries < TW_MAX_RESET_TRIES) {
if (do_soft_reset) if (do_soft_reset) {
TW_SOFT_RESET(tw_dev); TW_SOFT_RESET(tw_dev);
/* Clear pchip/response queue on 9550SX */
if (twa_empty_response_queue_large(tw_dev)) {
TW_PRINTK(tw_dev->host, TW_DRIVER, 0x36, "Response queue (large) empty failed during reset sequence");
do_soft_reset = 1;
tries++;
continue;
}
}
/* Make sure controller is in a good state */ /* Make sure controller is in a good state */
if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 60)) { if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 60)) {
...@@ -2034,7 +2068,10 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id ...@@ -2034,7 +2068,10 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
goto out_free_device_extension; goto out_free_device_extension;
} }
mem_addr = pci_resource_start(pdev, 1); if (pdev->device == PCI_DEVICE_ID_3WARE_9000)
mem_addr = pci_resource_start(pdev, 1);
else
mem_addr = pci_resource_start(pdev, 2);
/* Save base address */ /* Save base address */
tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE); tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
...@@ -2148,6 +2185,8 @@ static void twa_remove(struct pci_dev *pdev) ...@@ -2148,6 +2185,8 @@ static void twa_remove(struct pci_dev *pdev)
static struct pci_device_id twa_pci_tbl[] __devinitdata = { static struct pci_device_id twa_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000, { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ } { }
}; };
MODULE_DEVICE_TABLE(pci, twa_pci_tbl); MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
......
...@@ -267,7 +267,6 @@ static twa_message_type twa_error_table[] = { ...@@ -267,7 +267,6 @@ static twa_message_type twa_error_table[] = {
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000 #define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000 #define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000 #define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008
/* Status register bit definitions */ /* Status register bit definitions */
#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000 #define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
...@@ -285,9 +284,8 @@ static twa_message_type twa_error_table[] = { ...@@ -285,9 +284,8 @@ static twa_message_type twa_error_table[] = {
#define TW_STATUS_MICROCONTROLLER_READY 0x00002000 #define TW_STATUS_MICROCONTROLLER_READY 0x00002000
#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000 #define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000
#define TW_STATUS_EXPECTED_BITS 0x00002000 #define TW_STATUS_EXPECTED_BITS 0x00002000
#define TW_STATUS_UNEXPECTED_BITS 0x00F00008 #define TW_STATUS_UNEXPECTED_BITS 0x00F00000
#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008 #define TW_STATUS_VALID_INTERRUPT 0x00DF0000
#define TW_STATUS_VALID_INTERRUPT 0x00DF0008
/* RESPONSE QUEUE BIT DEFINITIONS */ /* RESPONSE QUEUE BIT DEFINITIONS */
#define TW_RESPONSE_ID_MASK 0x00000FF0 #define TW_RESPONSE_ID_MASK 0x00000FF0
...@@ -324,9 +322,9 @@ static twa_message_type twa_error_table[] = { ...@@ -324,9 +322,9 @@ static twa_message_type twa_error_table[] = {
/* Compatibility defines */ /* Compatibility defines */
#define TW_9000_ARCH_ID 0x5 #define TW_9000_ARCH_ID 0x5
#define TW_CURRENT_DRIVER_SRL 28 #define TW_CURRENT_DRIVER_SRL 30
#define TW_CURRENT_DRIVER_BUILD 9 #define TW_CURRENT_DRIVER_BUILD 80
#define TW_CURRENT_DRIVER_BRANCH 4 #define TW_CURRENT_DRIVER_BRANCH 0
/* Phase defines */ /* Phase defines */
#define TW_PHASE_INITIAL 0 #define TW_PHASE_INITIAL 0
...@@ -334,6 +332,7 @@ static twa_message_type twa_error_table[] = { ...@@ -334,6 +332,7 @@ static twa_message_type twa_error_table[] = {
#define TW_PHASE_SGLIST 2 #define TW_PHASE_SGLIST 2
/* Misc defines */ /* Misc defines */
#define TW_9550SX_DRAIN_COMPLETED 0xFFFF
#define TW_SECTOR_SIZE 512 #define TW_SECTOR_SIZE 512
#define TW_ALIGNMENT_9000 4 /* 4 bytes */ #define TW_ALIGNMENT_9000 4 /* 4 bytes */
#define TW_ALIGNMENT_9000_SGL 0x3 #define TW_ALIGNMENT_9000_SGL 0x3
...@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = { ...@@ -417,6 +416,9 @@ static twa_message_type twa_error_table[] = {
#ifndef PCI_DEVICE_ID_3WARE_9000 #ifndef PCI_DEVICE_ID_3WARE_9000
#define PCI_DEVICE_ID_3WARE_9000 0x1002 #define PCI_DEVICE_ID_3WARE_9000 0x1002
#endif #endif
#ifndef PCI_DEVICE_ID_3WARE_9550SX
#define PCI_DEVICE_ID_3WARE_9550SX 0x1003
#endif
/* Bitmask macros to eliminate bitfields */ /* Bitmask macros to eliminate bitfields */
...@@ -443,6 +445,7 @@ static twa_message_type twa_error_table[] = { ...@@ -443,6 +445,7 @@ static twa_message_type twa_error_table[] = {
#define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4) #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
#define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8)) #define TW_COMMAND_QUEUE_REG_ADDR(x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
#define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC) #define TW_RESPONSE_QUEUE_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0xC)
#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) ((unsigned char __iomem *)x->base_addr + 0x30)
#define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_ALL_INTERRUPTS(x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_ATTENTION_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x))) #define TW_CLEAR_HOST_INTERRUPT(x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
......
...@@ -99,6 +99,7 @@ obj-$(CONFIG_SCSI_DC395x) += dc395x.o ...@@ -99,6 +99,7 @@ obj-$(CONFIG_SCSI_DC395x) += dc395x.o
obj-$(CONFIG_SCSI_DC390T) += tmscsim.o obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_ACARD) += atp870u.o
obj-$(CONFIG_SCSI_SUNESP) += esp.o obj-$(CONFIG_SCSI_SUNESP) += esp.o
obj-$(CONFIG_SCSI_GDTH) += gdth.o obj-$(CONFIG_SCSI_GDTH) += gdth.o
......
This diff is collapsed.
#if (!defined(dprintk)) #if (!defined(dprintk))
# define dprintk(x) # define dprintk(x)
#endif #endif
/* eg: if (nblank(dprintk(x))) */
#define _nblank(x) #x
#define nblank(x) _nblank(x)[0]
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* D E F I N E S * D E F I N E S
...@@ -302,7 +306,6 @@ enum aac_queue_types { ...@@ -302,7 +306,6 @@ enum aac_queue_types {
*/ */
#define FsaNormal 1 #define FsaNormal 1
#define FsaHigh 2
/* /*
* Define the FIB. The FIB is the where all the requested data and * Define the FIB. The FIB is the where all the requested data and
...@@ -546,8 +549,6 @@ struct aac_queue { ...@@ -546,8 +549,6 @@ struct aac_queue {
/* This is only valid for adapter to host command queues. */ /* This is only valid for adapter to host command queues. */
spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */ spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */
spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */ spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */
unsigned long SavedIrql; /* Previous IRQL when the spin lock is taken */
u32 padding; /* Padding - FIXME - can remove I believe */
struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */ struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */
/* only valid for command queues which receive entries from the adapter. */ /* only valid for command queues which receive entries from the adapter. */
struct list_head pendingq; /* A queue of outstanding fib's to the adapter. */ struct list_head pendingq; /* A queue of outstanding fib's to the adapter. */
...@@ -776,7 +777,9 @@ struct fsa_dev_info { ...@@ -776,7 +777,9 @@ struct fsa_dev_info {
u64 last; u64 last;
u64 size; u64 size;
u32 type; u32 type;
u32 config_waiting_on;
u16 queue_depth; u16 queue_depth;
u8 config_needed;
u8 valid; u8 valid;
u8 ro; u8 ro;
u8 locked; u8 locked;
...@@ -1012,6 +1015,7 @@ struct aac_dev ...@@ -1012,6 +1015,7 @@ struct aac_dev
/* macro side-effects BEWARE */ /* macro side-effects BEWARE */
# define raw_io_interface \ # define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4) init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
u8 raw_io_64;
u8 printf_enabled; u8 printf_enabled;
}; };
...@@ -1362,8 +1366,10 @@ struct aac_srb_reply ...@@ -1362,8 +1366,10 @@ struct aac_srb_reply
#define VM_CtBlockVerify64 18 #define VM_CtBlockVerify64 18
#define VM_CtHostRead64 19 #define VM_CtHostRead64 19
#define VM_CtHostWrite64 20 #define VM_CtHostWrite64 20
#define VM_DrvErrTblLog 21
#define VM_NameServe64 22
#define MAX_VMCOMMAND_NUM 21 /* used for sizing stats array - leave last */ #define MAX_VMCOMMAND_NUM 23 /* used for sizing stats array - leave last */
/* /*
* Descriptive information (eg, vital stats) * Descriptive information (eg, vital stats)
...@@ -1472,6 +1478,7 @@ struct aac_mntent { ...@@ -1472,6 +1478,7 @@ struct aac_mntent {
manager (eg, filesystem) */ manager (eg, filesystem) */
__le32 altoid; /* != oid <==> snapshot or __le32 altoid; /* != oid <==> snapshot or
broken mirror exists */ broken mirror exists */
__le32 capacityhigh;
}; };
#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */ #define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */
...@@ -1707,6 +1714,7 @@ extern struct aac_common aac_config; ...@@ -1707,6 +1714,7 @@ extern struct aac_common aac_config;
#define AifCmdJobProgress 2 /* Progress report */ #define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */ #define AifJobCtrZero 101 /* Array Zero progress */
#define AifJobStsSuccess 1 /* Job completes */ #define AifJobStsSuccess 1 /* Job completes */
#define AifJobStsRunning 102 /* Job running */
#define AifCmdAPIReport 3 /* Report from other user of API */ #define AifCmdAPIReport 3 /* Report from other user of API */
#define AifCmdDriverNotify 4 /* Notify host driver of event */ #define AifCmdDriverNotify 4 /* Notify host driver of event */
#define AifDenMorphComplete 200 /* A morph operation completed */ #define AifDenMorphComplete 200 /* A morph operation completed */
...@@ -1777,6 +1785,7 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size); ...@@ -1777,6 +1785,7 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size);
struct aac_driver_ident* aac_get_driver_ident(int devtype); struct aac_driver_ident* aac_get_driver_ident(int devtype);
int aac_get_adapter_info(struct aac_dev* dev); int aac_get_adapter_info(struct aac_dev* dev);
int aac_send_shutdown(struct aac_dev *dev); int aac_send_shutdown(struct aac_dev *dev);
int probe_container(struct aac_dev *dev, int cid);
extern int numacb; extern int numacb;
extern int acbsize; extern int acbsize;
extern char aac_driver_version[]; extern char aac_driver_version[];
...@@ -195,7 +195,7 @@ int aac_send_shutdown(struct aac_dev * dev) ...@@ -195,7 +195,7 @@ int aac_send_shutdown(struct aac_dev * dev)
fibctx, fibctx,
sizeof(struct aac_close), sizeof(struct aac_close),
FsaNormal, FsaNormal,
1, 1, -2 /* Timeout silently */, 1,
NULL, NULL); NULL, NULL);
if (status == 0) if (status == 0)
...@@ -313,8 +313,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) ...@@ -313,8 +313,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->max_fib_size = sizeof(struct hw_fib); dev->max_fib_size = sizeof(struct hw_fib);
dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
- sizeof(struct aac_fibhdr) - sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgmap)) - sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgmap); / sizeof(struct sgentry);
dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
(status[0] == 0x00000001)) {
if (status[1] & AAC_OPT_NEW_COMM_64)
dev->raw_io_64 = 1;
}
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS, if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4)) status+0, status+1, status+2, status+3, status+4))
...@@ -342,8 +349,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) ...@@ -342,8 +349,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->max_fib_size = 512; dev->max_fib_size = 512;
dev->sg_tablesize = host->sg_tablesize dev->sg_tablesize = host->sg_tablesize
= (512 - sizeof(struct aac_fibhdr) = (512 - sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgmap)) - sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgmap); / sizeof(struct sgentry);
host->can_queue = AAC_NUM_IO_FIB; host->can_queue = AAC_NUM_IO_FIB;
} else if (acbsize == 2048) { } else if (acbsize == 2048) {
host->max_sectors = 512; host->max_sectors = 512;
......
This diff is collapsed.
...@@ -748,7 +748,8 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -748,7 +748,8 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
unique_id++; unique_id++;
} }
if (pci_enable_device(pdev)) error = pci_enable_device(pdev);
if (error)
goto out; goto out;
if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL) || if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL) ||
...@@ -772,6 +773,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -772,6 +773,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
shost->irq = pdev->irq; shost->irq = pdev->irq;
shost->base = pci_resource_start(pdev, 0); shost->base = pci_resource_start(pdev, 0);
shost->unique_id = unique_id; shost->unique_id = unique_id;
shost->max_cmd_len = 16;
aac = (struct aac_dev *)shost->hostdata; aac = (struct aac_dev *)shost->hostdata;
aac->scsi_host_ptr = shost; aac->scsi_host_ptr = shost;
...@@ -799,7 +801,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev, ...@@ -799,7 +801,9 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out_free_fibs; goto out_free_fibs;
aac->maximum_num_channels = aac_drivers[index].channels; aac->maximum_num_channels = aac_drivers[index].channels;
aac_get_adapter_info(aac); error = aac_get_adapter_info(aac);
if (error < 0)
goto out_deinit;
/* /*
* Lets override negotiations and drop the maximum SG limit to 34 * Lets override negotiations and drop the maximum SG limit to 34
...@@ -927,8 +931,8 @@ static int __init aac_init(void) ...@@ -927,8 +931,8 @@ static int __init aac_init(void)
printk(KERN_INFO "Adaptec %s driver (%s)\n", printk(KERN_INFO "Adaptec %s driver (%s)\n",
AAC_DRIVERNAME, aac_driver_version); AAC_DRIVERNAME, aac_driver_version);
error = pci_module_init(&aac_pci_driver); error = pci_register_driver(&aac_pci_driver);
if (error) if (error < 0)
return error; return error;
aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops); aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops);
......
...@@ -112,6 +112,9 @@ aic7770_remove(struct device *dev) ...@@ -112,6 +112,9 @@ aic7770_remove(struct device *dev)
struct ahc_softc *ahc = dev_get_drvdata(dev); struct ahc_softc *ahc = dev_get_drvdata(dev);
u_long s; u_long s;
if (ahc->platform_data && ahc->platform_data->host)
scsi_remove_host(ahc->platform_data->host);
ahc_lock(ahc, &s); ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE); ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s); ahc_unlock(ahc, &s);
......
...@@ -1192,11 +1192,6 @@ ahd_platform_free(struct ahd_softc *ahd) ...@@ -1192,11 +1192,6 @@ ahd_platform_free(struct ahd_softc *ahd)
int i, j; int i, j;
if (ahd->platform_data != NULL) { if (ahd->platform_data != NULL) {
if (ahd->platform_data->host != NULL) {
scsi_remove_host(ahd->platform_data->host);
scsi_host_put(ahd->platform_data->host);
}
/* destroy all of the device and target objects */ /* destroy all of the device and target objects */
for (i = 0; i < AHD_NUM_TARGETS; i++) { for (i = 0; i < AHD_NUM_TARGETS; i++) {
starget = ahd->platform_data->starget[i]; starget = ahd->platform_data->starget[i];
...@@ -1226,6 +1221,9 @@ ahd_platform_free(struct ahd_softc *ahd) ...@@ -1226,6 +1221,9 @@ ahd_platform_free(struct ahd_softc *ahd)
release_mem_region(ahd->platform_data->mem_busaddr, release_mem_region(ahd->platform_data->mem_busaddr,
0x1000); 0x1000);
} }
if (ahd->platform_data->host)
scsi_host_put(ahd->platform_data->host);
free(ahd->platform_data, M_DEVBUF); free(ahd->platform_data, M_DEVBUF);
} }
} }
......
...@@ -95,6 +95,9 @@ ahd_linux_pci_dev_remove(struct pci_dev *pdev) ...@@ -95,6 +95,9 @@ ahd_linux_pci_dev_remove(struct pci_dev *pdev)
struct ahd_softc *ahd = pci_get_drvdata(pdev); struct ahd_softc *ahd = pci_get_drvdata(pdev);
u_long s; u_long s;
if (ahd->platform_data && ahd->platform_data->host)
scsi_remove_host(ahd->platform_data->host);
ahd_lock(ahd, &s); ahd_lock(ahd, &s);
ahd_intr_enable(ahd, FALSE); ahd_intr_enable(ahd, FALSE);
ahd_unlock(ahd, &s); ahd_unlock(ahd, &s);
......
...@@ -1209,11 +1209,6 @@ ahc_platform_free(struct ahc_softc *ahc) ...@@ -1209,11 +1209,6 @@ ahc_platform_free(struct ahc_softc *ahc)
int i, j; int i, j;
if (ahc->platform_data != NULL) { if (ahc->platform_data != NULL) {
if (ahc->platform_data->host != NULL) {
scsi_remove_host(ahc->platform_data->host);
scsi_host_put(ahc->platform_data->host);
}
/* destroy all of the device and target objects */ /* destroy all of the device and target objects */
for (i = 0; i < AHC_NUM_TARGETS; i++) { for (i = 0; i < AHC_NUM_TARGETS; i++) {
starget = ahc->platform_data->starget[i]; starget = ahc->platform_data->starget[i];
...@@ -1242,6 +1237,9 @@ ahc_platform_free(struct ahc_softc *ahc) ...@@ -1242,6 +1237,9 @@ ahc_platform_free(struct ahc_softc *ahc)
0x1000); 0x1000);
} }
if (ahc->platform_data->host)
scsi_host_put(ahc->platform_data->host);
free(ahc->platform_data, M_DEVBUF); free(ahc->platform_data, M_DEVBUF);
} }
} }
......
...@@ -143,6 +143,9 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev) ...@@ -143,6 +143,9 @@ ahc_linux_pci_dev_remove(struct pci_dev *pdev)
struct ahc_softc *ahc = pci_get_drvdata(pdev); struct ahc_softc *ahc = pci_get_drvdata(pdev);
u_long s; u_long s;
if (ahc->platform_data && ahc->platform_data->host)
scsi_remove_host(ahc->platform_data->host);
ahc_lock(ahc, &s); ahc_lock(ahc, &s);
ahc_intr_enable(ahc, FALSE); ahc_intr_enable(ahc, FALSE);
ahc_unlock(ahc, &s); ahc_unlock(ahc, &s);
......
...@@ -176,6 +176,7 @@ void scsi_remove_host(struct Scsi_Host *shost) ...@@ -176,6 +176,7 @@ void scsi_remove_host(struct Scsi_Host *shost)
transport_unregister_device(&shost->shost_gendev); transport_unregister_device(&shost->shost_gendev);
class_device_unregister(&shost->shost_classdev); class_device_unregister(&shost->shost_classdev);
device_del(&shost->shost_gendev); device_del(&shost->shost_gendev);
scsi_proc_hostdir_rm(shost->hostt);
} }
EXPORT_SYMBOL(scsi_remove_host); EXPORT_SYMBOL(scsi_remove_host);
...@@ -262,7 +263,6 @@ static void scsi_host_dev_release(struct device *dev) ...@@ -262,7 +263,6 @@ static void scsi_host_dev_release(struct device *dev)
if (shost->work_q) if (shost->work_q)
destroy_workqueue(shost->work_q); destroy_workqueue(shost->work_q);
scsi_proc_hostdir_rm(shost->hostt);
scsi_destroy_command_freelist(shost); scsi_destroy_command_freelist(shost);
kfree(shost->shost_data); kfree(shost->shost_data);
......
...@@ -973,10 +973,10 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost) ...@@ -973,10 +973,10 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
if ((phba->fc_flag & FC_FABRIC) || if ((phba->fc_flag & FC_FABRIC) ||
((phba->fc_topology == TOPOLOGY_LOOP) && ((phba->fc_topology == TOPOLOGY_LOOP) &&
(phba->fc_flag & FC_PUBLIC_LOOP))) (phba->fc_flag & FC_PUBLIC_LOOP)))
node_name = wwn_to_u64(phba->fc_fabparam.nodeName.wwn); node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
else else
/* fabric is local port if there is no F/FL_Port */ /* fabric is local port if there is no F/FL_Port */
node_name = wwn_to_u64(phba->fc_nodename.wwn); node_name = wwn_to_u64(phba->fc_nodename.u.wwn);
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
...@@ -1110,7 +1110,7 @@ lpfc_get_starget_node_name(struct scsi_target *starget) ...@@ -1110,7 +1110,7 @@ lpfc_get_starget_node_name(struct scsi_target *starget)
/* Search the mapped list for this target ID */ /* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) { if (starget->id == ndlp->nlp_sid) {
node_name = wwn_to_u64(ndlp->nlp_nodename.wwn); node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
break; break;
} }
} }
...@@ -1131,7 +1131,7 @@ lpfc_get_starget_port_name(struct scsi_target *starget) ...@@ -1131,7 +1131,7 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
/* Search the mapped list for this target ID */ /* Search the mapped list for this target ID */
list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
if (starget->id == ndlp->nlp_sid) { if (starget->id == ndlp->nlp_sid) {
port_name = wwn_to_u64(ndlp->nlp_portname.wwn); port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
break; break;
} }
} }
......
...@@ -1019,8 +1019,8 @@ lpfc_register_remote_port(struct lpfc_hba * phba, ...@@ -1019,8 +1019,8 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
struct fc_rport_identifiers rport_ids; struct fc_rport_identifiers rport_ids;
/* Remote port has reappeared. Re-register w/ FC transport */ /* Remote port has reappeared. Re-register w/ FC transport */
rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.wwn); rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.wwn); rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
rport_ids.port_id = ndlp->nlp_DID; rport_ids.port_id = ndlp->nlp_DID;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
if (ndlp->nlp_type & NLP_FCP_TARGET) if (ndlp->nlp_type & NLP_FCP_TARGET)
......
...@@ -280,9 +280,9 @@ struct lpfc_name { ...@@ -280,9 +280,9 @@ struct lpfc_name {
#define NAME_CCITT_GR_TYPE 0xE #define NAME_CCITT_GR_TYPE 0xE
uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */ uint8_t IEEEextLsb; /* FC Word 0, bit 16:23, IEEE extended Lsb */
uint8_t IEEE[6]; /* FC IEEE address */ uint8_t IEEE[6]; /* FC IEEE address */
}; } s;
uint8_t wwn[8]; uint8_t wwn[8];
}; } u;
}; };
struct csp { struct csp {
......
...@@ -285,7 +285,7 @@ lpfc_config_port_post(struct lpfc_hba * phba) ...@@ -285,7 +285,7 @@ lpfc_config_port_post(struct lpfc_hba * phba)
if (phba->SerialNumber[0] == 0) { if (phba->SerialNumber[0] == 0) {
uint8_t *outptr; uint8_t *outptr;
outptr = (uint8_t *) & phba->fc_nodename.IEEE[0]; outptr = &phba->fc_nodename.u.s.IEEE[0];
for (i = 0; i < 12; i++) { for (i = 0; i < 12; i++) {
status = *outptr++; status = *outptr++;
j = ((status & 0xf0) >> 4); j = ((status & 0xf0) >> 4);
...@@ -1523,8 +1523,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1523,8 +1523,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
* Must done after lpfc_sli_hba_setup() * Must done after lpfc_sli_hba_setup()
*/ */
fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.wwn); fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.u.wwn);
fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.wwn); fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.u.wwn);
fc_host_supported_classes(host) = FC_COS_CLASS3; fc_host_supported_classes(host) = FC_COS_CLASS3;
memset(fc_host_supported_fc4s(host), 0, memset(fc_host_supported_fc4s(host), 0,
......
...@@ -621,8 +621,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) ...@@ -621,8 +621,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
if(islogical) { if(islogical) {
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
case TEST_UNIT_READY: case TEST_UNIT_READY:
memset(cmd->request_buffer, 0, cmd->request_bufflen);
#if MEGA_HAVE_CLUSTERING #if MEGA_HAVE_CLUSTERING
/* /*
* Do we support clustering and is the support enabled * Do we support clustering and is the support enabled
...@@ -652,11 +650,28 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) ...@@ -652,11 +650,28 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
return NULL; return NULL;
#endif #endif
case MODE_SENSE: case MODE_SENSE: {
char *buf;
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *)cmd->request_buffer;
buf = kmap_atomic(sg->page, KM_IRQ0) +
sg->offset;
} else
buf = cmd->request_buffer;
memset(cmd->request_buffer, 0, cmd->cmnd[4]); memset(cmd->request_buffer, 0, cmd->cmnd[4]);
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *)cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
cmd->result = (DID_OK << 16); cmd->result = (DID_OK << 16);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
return NULL; return NULL;
}
case READ_CAPACITY: case READ_CAPACITY:
case INQUIRY: case INQUIRY:
...@@ -1685,14 +1700,23 @@ mega_rundoneq (adapter_t *adapter) ...@@ -1685,14 +1700,23 @@ mega_rundoneq (adapter_t *adapter)
static void static void
mega_free_scb(adapter_t *adapter, scb_t *scb) mega_free_scb(adapter_t *adapter, scb_t *scb)
{ {
unsigned long length;
switch( scb->dma_type ) { switch( scb->dma_type ) {
case MEGA_DMA_TYPE_NONE: case MEGA_DMA_TYPE_NONE:
break; break;
case MEGA_BULK_DATA: case MEGA_BULK_DATA:
if (scb->cmd->use_sg == 0)
length = scb->cmd->request_bufflen;
else {
struct scatterlist *sgl =
(struct scatterlist *)scb->cmd->request_buffer;
length = sgl->length;
}
pci_unmap_page(adapter->dev, scb->dma_h_bulkdata, pci_unmap_page(adapter->dev, scb->dma_h_bulkdata,
scb->cmd->request_bufflen, scb->dma_direction); length, scb->dma_direction);
break; break;
case MEGA_SGLIST: case MEGA_SGLIST:
...@@ -1741,6 +1765,7 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) ...@@ -1741,6 +1765,7 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
struct scatterlist *sgl; struct scatterlist *sgl;
struct page *page; struct page *page;
unsigned long offset; unsigned long offset;
unsigned int length;
Scsi_Cmnd *cmd; Scsi_Cmnd *cmd;
int sgcnt; int sgcnt;
int idx; int idx;
...@@ -1748,14 +1773,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) ...@@ -1748,14 +1773,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
cmd = scb->cmd; cmd = scb->cmd;
/* Scatter-gather not used */ /* Scatter-gather not used */
if( !cmd->use_sg ) { if( cmd->use_sg == 0 || (cmd->use_sg == 1 &&
!adapter->has_64bit_addr)) {
page = virt_to_page(cmd->request_buffer);
offset = offset_in_page(cmd->request_buffer); if (cmd->use_sg == 0) {
page = virt_to_page(cmd->request_buffer);
offset = offset_in_page(cmd->request_buffer);
length = cmd->request_bufflen;
} else {
sgl = (struct scatterlist *)cmd->request_buffer;
page = sgl->page;
offset = sgl->offset;
length = sgl->length;
}
scb->dma_h_bulkdata = pci_map_page(adapter->dev, scb->dma_h_bulkdata = pci_map_page(adapter->dev,
page, offset, page, offset,
cmd->request_bufflen, length,
scb->dma_direction); scb->dma_direction);
scb->dma_type = MEGA_BULK_DATA; scb->dma_type = MEGA_BULK_DATA;
...@@ -1765,14 +1799,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) ...@@ -1765,14 +1799,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
*/ */
if( adapter->has_64bit_addr ) { if( adapter->has_64bit_addr ) {
scb->sgl64[0].address = scb->dma_h_bulkdata; scb->sgl64[0].address = scb->dma_h_bulkdata;
scb->sgl64[0].length = cmd->request_bufflen; scb->sgl64[0].length = length;
*buf = (u32)scb->sgl_dma_addr; *buf = (u32)scb->sgl_dma_addr;
*len = (u32)cmd->request_bufflen; *len = (u32)length;
return 1; return 1;
} }
else { else {
*buf = (u32)scb->dma_h_bulkdata; *buf = (u32)scb->dma_h_bulkdata;
*len = (u32)cmd->request_bufflen; *len = (u32)length;
} }
return 0; return 0;
} }
...@@ -1791,27 +1825,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len) ...@@ -1791,27 +1825,23 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
if( sgcnt > adapter->sglen ) BUG(); if( sgcnt > adapter->sglen ) BUG();
*len = 0;
for( idx = 0; idx < sgcnt; idx++, sgl++ ) { for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
if( adapter->has_64bit_addr ) { if( adapter->has_64bit_addr ) {
scb->sgl64[idx].address = sg_dma_address(sgl); scb->sgl64[idx].address = sg_dma_address(sgl);
scb->sgl64[idx].length = sg_dma_len(sgl); *len += scb->sgl64[idx].length = sg_dma_len(sgl);
} }
else { else {
scb->sgl[idx].address = sg_dma_address(sgl); scb->sgl[idx].address = sg_dma_address(sgl);
scb->sgl[idx].length = sg_dma_len(sgl); *len += scb->sgl[idx].length = sg_dma_len(sgl);
} }
} }
/* Reset pointer and length fields */ /* Reset pointer and length fields */
*buf = scb->sgl_dma_addr; *buf = scb->sgl_dma_addr;
/*
* For passthru command, dataxferlen must be set, even for commands
* with a sg list
*/
*len = (u32)cmd->request_bufflen;
/* Return count of SG requests */ /* Return count of SG requests */
return sgcnt; return sgcnt;
} }
......
...@@ -76,3 +76,12 @@ config MEGARAID_LEGACY ...@@ -76,3 +76,12 @@ config MEGARAID_LEGACY
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called megaraid module will be called megaraid
endif endif
config MEGARAID_SAS
tristate "LSI Logic MegaRAID SAS RAID Module"
depends on PCI && SCSI
help
Module for LSI Logic's SAS based RAID controllers.
To compile this driver as a module, choose 'm' here.
Module will be called megaraid_sas
obj-$(CONFIG_MEGARAID_MM) += megaraid_mm.o obj-$(CONFIG_MEGARAID_MM) += megaraid_mm.o
obj-$(CONFIG_MEGARAID_MAILBOX) += megaraid_mbox.o obj-$(CONFIG_MEGARAID_MAILBOX) += megaraid_mbox.o
obj-$(CONFIG_MEGARAID_SAS) += megaraid_sas.o
This diff is collapsed.
This diff is collapsed.
...@@ -330,6 +330,8 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat, ...@@ -330,6 +330,8 @@ qla2x00_update_login_fcport(scsi_qla_host_t *ha, struct mbx_entry *mbxstat,
fcport->flags &= ~FCF_FAILOVER_NEEDED; fcport->flags &= ~FCF_FAILOVER_NEEDED;
fcport->iodesc_idx_sent = IODESC_INVALID_INDEX; fcport->iodesc_idx_sent = IODESC_INVALID_INDEX;
atomic_set(&fcport->state, FCS_ONLINE); atomic_set(&fcport->state, FCS_ONLINE);
if (fcport->rport)
fc_remote_port_unblock(fcport->rport);
} }
......
...@@ -587,6 +587,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, ...@@ -587,6 +587,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
if (sdev->scsi_level >= 2 || if (sdev->scsi_level >= 2 ||
(sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
sdev->scsi_level++; sdev->scsi_level++;
sdev->sdev_target->scsi_level = sdev->scsi_level;
return 0; return 0;
} }
...@@ -771,6 +772,15 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) ...@@ -771,6 +772,15 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
static inline void scsi_destroy_sdev(struct scsi_device *sdev)
{
if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
}
/** /**
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
* @starget: pointer to target device structure * @starget: pointer to target device structure
...@@ -803,9 +813,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, ...@@ -803,9 +813,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
* The rescan flag is used as an optimization, the first scan of a * The rescan flag is used as an optimization, the first scan of a
* host adapter calls into here with rescan == 0. * host adapter calls into here with rescan == 0.
*/ */
if (rescan) { sdev = scsi_device_lookup_by_target(starget, lun);
sdev = scsi_device_lookup_by_target(starget, lun); if (sdev) {
if (sdev) { if (rescan || sdev->sdev_state != SDEV_CREATED) {
SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
"scsi scan: device exists on %s\n", "scsi scan: device exists on %s\n",
sdev->sdev_gendev.bus_id)); sdev->sdev_gendev.bus_id));
...@@ -820,9 +830,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, ...@@ -820,9 +830,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
sdev->model); sdev->model);
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
} scsi_device_put(sdev);
} else
sdev = scsi_alloc_sdev(starget, lun, hostdata); sdev = scsi_alloc_sdev(starget, lun, hostdata);
if (!sdev) if (!sdev)
goto out; goto out;
...@@ -877,12 +887,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, ...@@ -877,12 +887,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
res = SCSI_SCAN_NO_RESPONSE; res = SCSI_SCAN_NO_RESPONSE;
} }
} }
} else { } else
if (sdev->host->hostt->slave_destroy) scsi_destroy_sdev(sdev);
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
}
out: out:
return res; return res;
} }
...@@ -1054,7 +1060,7 @@ EXPORT_SYMBOL(int_to_scsilun); ...@@ -1054,7 +1060,7 @@ EXPORT_SYMBOL(int_to_scsilun);
* 0: scan completed (or no memory, so further scanning is futile) * 0: scan completed (or no memory, so further scanning is futile)
* 1: no report lun scan, or not configured * 1: no report lun scan, or not configured
**/ **/
static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
int rescan) int rescan)
{ {
char devname[64]; char devname[64];
...@@ -1067,7 +1073,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1067,7 +1073,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
struct scsi_lun *lunp, *lun_data; struct scsi_lun *lunp, *lun_data;
u8 *data; u8 *data;
struct scsi_sense_hdr sshdr; struct scsi_sense_hdr sshdr;
struct scsi_target *starget = scsi_target(sdev); struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
/* /*
* Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
...@@ -1075,15 +1082,23 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1075,15 +1082,23 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
* support more than 8 LUNs. * support more than 8 LUNs.
*/ */
if ((bflags & BLIST_NOREPORTLUN) || if ((bflags & BLIST_NOREPORTLUN) ||
sdev->scsi_level < SCSI_2 || starget->scsi_level < SCSI_2 ||
(sdev->scsi_level < SCSI_3 && (starget->scsi_level < SCSI_3 &&
(!(bflags & BLIST_REPORTLUN2) || sdev->host->max_lun <= 8)) ) (!(bflags & BLIST_REPORTLUN2) || shost->max_lun <= 8)) )
return 1; return 1;
if (bflags & BLIST_NOLUN) if (bflags & BLIST_NOLUN)
return 0; return 0;
if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
sdev = scsi_alloc_sdev(starget, 0, NULL);
if (!sdev)
return 0;
if (scsi_device_get(sdev))
return 0;
}
sprintf(devname, "host %d channel %d id %d", sprintf(devname, "host %d channel %d id %d",
sdev->host->host_no, sdev->channel, sdev->id); shost->host_no, sdev->channel, sdev->id);
/* /*
* Allocate enough to hold the header (the same size as one scsi_lun) * Allocate enough to hold the header (the same size as one scsi_lun)
...@@ -1098,8 +1113,10 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1098,8 +1113,10 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun); length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
lun_data = kmalloc(length, GFP_ATOMIC | lun_data = kmalloc(length, GFP_ATOMIC |
(sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
if (!lun_data) if (!lun_data) {
printk(ALLOC_FAILURE_MSG, __FUNCTION__);
goto out; goto out;
}
scsi_cmd[0] = REPORT_LUNS; scsi_cmd[0] = REPORT_LUNS;
...@@ -1201,10 +1218,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1201,10 +1218,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
for (i = 0; i < sizeof(struct scsi_lun); i++) for (i = 0; i < sizeof(struct scsi_lun); i++)
printk("%02x", data[i]); printk("%02x", data[i]);
printk(" has a LUN larger than currently supported.\n"); printk(" has a LUN larger than currently supported.\n");
} else if (lun == 0) {
/*
* LUN 0 has already been scanned.
*/
} else if (lun > sdev->host->max_lun) { } else if (lun > sdev->host->max_lun) {
printk(KERN_WARNING "scsi: %s lun%d has a LUN larger" printk(KERN_WARNING "scsi: %s lun%d has a LUN larger"
" than allowed by the host adapter\n", " than allowed by the host adapter\n",
...@@ -1227,13 +1240,13 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, ...@@ -1227,13 +1240,13 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
} }
kfree(lun_data); kfree(lun_data);
return 0;
out: out:
/* scsi_device_put(sdev);
* We are out of memory, don't try scanning any further. if (sdev->sdev_state == SDEV_CREATED)
*/ /*
printk(ALLOC_FAILURE_MSG, __FUNCTION__); * the sdev we used didn't appear in the report luns scan
*/
scsi_destroy_sdev(sdev);
return 0; return 0;
} }
...@@ -1299,7 +1312,6 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, ...@@ -1299,7 +1312,6 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
struct Scsi_Host *shost = dev_to_shost(parent); struct Scsi_Host *shost = dev_to_shost(parent);
int bflags = 0; int bflags = 0;
int res; int res;
struct scsi_device *sdev = NULL;
struct scsi_target *starget; struct scsi_target *starget;
if (shost->this_id == id) if (shost->this_id == id)
...@@ -1325,27 +1337,16 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, ...@@ -1325,27 +1337,16 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
* Scan LUN 0, if there is some response, scan further. Ideally, we * Scan LUN 0, if there is some response, scan further. Ideally, we
* would not configure LUN 0 until all LUNs are scanned. * would not configure LUN 0 until all LUNs are scanned.
*/ */
res = scsi_probe_and_add_lun(starget, 0, &bflags, &sdev, rescan, NULL); res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
if (res == SCSI_SCAN_LUN_PRESENT) { if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
if (scsi_report_lun_scan(sdev, bflags, rescan) != 0) if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
/* /*
* The REPORT LUN did not scan the target, * The REPORT LUN did not scan the target,
* do a sequential scan. * do a sequential scan.
*/ */
scsi_sequential_lun_scan(starget, bflags, scsi_sequential_lun_scan(starget, bflags,
res, sdev->scsi_level, rescan); res, starget->scsi_level, rescan);
} else if (res == SCSI_SCAN_TARGET_PRESENT) {
/*
* There's a target here, but lun 0 is offline so we
* can't use the report_lun scan. Fall back to a
* sequential lun scan with a bflags of SPARSELUN and
* a default scsi level of SCSI_2
*/
scsi_sequential_lun_scan(starget, BLIST_SPARSELUN,
SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
} }
if (sdev)
scsi_device_put(sdev);
out_reap: out_reap:
/* now determine if the target has any children at all /* now determine if the target has any children at all
...@@ -1542,10 +1543,7 @@ void scsi_free_host_dev(struct scsi_device *sdev) ...@@ -1542,10 +1543,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
{ {
BUG_ON(sdev->id != sdev->host->this_id); BUG_ON(sdev->id != sdev->host->this_id);
if (sdev->host->hostt->slave_destroy) scsi_destroy_sdev(sdev);
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(&sdev->sdev_gendev);
put_device(&sdev->sdev_gendev);
} }
EXPORT_SYMBOL(scsi_free_host_dev); EXPORT_SYMBOL(scsi_free_host_dev);
...@@ -628,17 +628,16 @@ sas_rphy_delete(struct sas_rphy *rphy) ...@@ -628,17 +628,16 @@ sas_rphy_delete(struct sas_rphy *rphy)
struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
transport_destroy_device(&rphy->dev); scsi_remove_target(dev);
scsi_remove_target(&rphy->dev); transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
spin_lock(&sas_host->lock); spin_lock(&sas_host->lock);
list_del(&rphy->list); list_del(&rphy->list);
spin_unlock(&sas_host->lock); spin_unlock(&sas_host->lock);
transport_remove_device(dev);
device_del(dev);
transport_destroy_device(dev);
put_device(&parent->dev); put_device(&parent->dev);
} }
EXPORT_SYMBOL(sas_rphy_delete); EXPORT_SYMBOL(sas_rphy_delete);
......
...@@ -185,6 +185,7 @@ ...@@ -185,6 +185,7 @@
#define PCI_DEVICE_ID_LSI_61C102 0x0901 #define PCI_DEVICE_ID_LSI_61C102 0x0901
#define PCI_DEVICE_ID_LSI_63C815 0x1000 #define PCI_DEVICE_ID_LSI_63C815 0x1000
#define PCI_DEVICE_ID_LSI_SAS1064 0x0050 #define PCI_DEVICE_ID_LSI_SAS1064 0x0050
#define PCI_DEVICE_ID_LSI_SAS1064R 0x0411
#define PCI_DEVICE_ID_LSI_SAS1066 0x005E #define PCI_DEVICE_ID_LSI_SAS1066 0x005E
#define PCI_DEVICE_ID_LSI_SAS1068 0x0054 #define PCI_DEVICE_ID_LSI_SAS1068 0x0054
#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C #define PCI_DEVICE_ID_LSI_SAS1064A 0x005C
...@@ -560,6 +561,7 @@ ...@@ -560,6 +561,7 @@
#define PCI_VENDOR_ID_DELL 0x1028 #define PCI_VENDOR_ID_DELL 0x1028
#define PCI_DEVICE_ID_DELL_RACIII 0x0008 #define PCI_DEVICE_ID_DELL_RACIII 0x0008
#define PCI_DEVICE_ID_DELL_RAC4 0x0012 #define PCI_DEVICE_ID_DELL_RAC4 0x0012
#define PCI_DEVICE_ID_DELL_PERC5 0x0015
#define PCI_VENDOR_ID_MATROX 0x102B #define PCI_VENDOR_ID_MATROX 0x102B
#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 #define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
......
...@@ -163,6 +163,7 @@ struct scsi_target { ...@@ -163,6 +163,7 @@ struct scsi_target {
unsigned int id; /* target id ... replace unsigned int id; /* target id ... replace
* scsi_device.id eventually */ * scsi_device.id eventually */
unsigned long create:1; /* signal that it needs to be added */ unsigned long create:1; /* signal that it needs to be added */
char scsi_level;
void *hostdata; /* available to low-level driver */ void *hostdata; /* available to low-level driver */
unsigned long starget_data[0]; /* for the transport */ unsigned long starget_data[0]; /* for the transport */
/* starget_data must be the last element!!!! */ /* starget_data must be the last element!!!! */
......
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