diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/DAC960.c | 156 | ||||
-rw-r--r-- | drivers/block/cciss.c | 834 | ||||
-rw-r--r-- | drivers/block/cciss.h | 12 | ||||
-rw-r--r-- | drivers/block/cpqarray.c | 63 | ||||
-rw-r--r-- | drivers/block/loop.c | 2 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 39 |
6 files changed, 697 insertions, 409 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6fa7b0fdbdfd..eb4fa1943944 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/seq_file.h> | ||
41 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
43 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
@@ -6422,16 +6423,10 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller, | |||
6422 | return true; | 6423 | return true; |
6423 | } | 6424 | } |
6424 | 6425 | ||
6425 | 6426 | static int dac960_proc_show(struct seq_file *m, void *v) | |
6426 | /* | ||
6427 | DAC960_ProcReadStatus implements reading /proc/rd/status. | ||
6428 | */ | ||
6429 | |||
6430 | static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset, | ||
6431 | int Count, int *EOF, void *Data) | ||
6432 | { | 6427 | { |
6433 | unsigned char *StatusMessage = "OK\n"; | 6428 | unsigned char *StatusMessage = "OK\n"; |
6434 | int ControllerNumber, BytesAvailable; | 6429 | int ControllerNumber; |
6435 | for (ControllerNumber = 0; | 6430 | for (ControllerNumber = 0; |
6436 | ControllerNumber < DAC960_ControllerCount; | 6431 | ControllerNumber < DAC960_ControllerCount; |
6437 | ControllerNumber++) | 6432 | ControllerNumber++) |
@@ -6444,52 +6439,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset, | |||
6444 | break; | 6439 | break; |
6445 | } | 6440 | } |
6446 | } | 6441 | } |
6447 | BytesAvailable = strlen(StatusMessage) - Offset; | 6442 | seq_puts(m, StatusMessage); |
6448 | if (Count >= BytesAvailable) | 6443 | return 0; |
6449 | { | ||
6450 | Count = BytesAvailable; | ||
6451 | *EOF = true; | ||
6452 | } | ||
6453 | if (Count <= 0) return 0; | ||
6454 | *Start = Page; | ||
6455 | memcpy(Page, &StatusMessage[Offset], Count); | ||
6456 | return Count; | ||
6457 | } | 6444 | } |
6458 | 6445 | ||
6446 | static int dac960_proc_open(struct inode *inode, struct file *file) | ||
6447 | { | ||
6448 | return single_open(file, dac960_proc_show, NULL); | ||
6449 | } | ||
6459 | 6450 | ||
6460 | /* | 6451 | static const struct file_operations dac960_proc_fops = { |
6461 | DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status. | 6452 | .owner = THIS_MODULE, |
6462 | */ | 6453 | .open = dac960_proc_open, |
6454 | .read = seq_read, | ||
6455 | .llseek = seq_lseek, | ||
6456 | .release = single_release, | ||
6457 | }; | ||
6463 | 6458 | ||
6464 | static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset, | 6459 | static int dac960_initial_status_proc_show(struct seq_file *m, void *v) |
6465 | int Count, int *EOF, void *Data) | ||
6466 | { | 6460 | { |
6467 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6461 | DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; |
6468 | int BytesAvailable = Controller->InitialStatusLength - Offset; | 6462 | seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer); |
6469 | if (Count >= BytesAvailable) | 6463 | return 0; |
6470 | { | ||
6471 | Count = BytesAvailable; | ||
6472 | *EOF = true; | ||
6473 | } | ||
6474 | if (Count <= 0) return 0; | ||
6475 | *Start = Page; | ||
6476 | memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count); | ||
6477 | return Count; | ||
6478 | } | 6464 | } |
6479 | 6465 | ||
6466 | static int dac960_initial_status_proc_open(struct inode *inode, struct file *file) | ||
6467 | { | ||
6468 | return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data); | ||
6469 | } | ||
6480 | 6470 | ||
6481 | /* | 6471 | static const struct file_operations dac960_initial_status_proc_fops = { |
6482 | DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status. | 6472 | .owner = THIS_MODULE, |
6483 | */ | 6473 | .open = dac960_initial_status_proc_open, |
6474 | .read = seq_read, | ||
6475 | .llseek = seq_lseek, | ||
6476 | .release = single_release, | ||
6477 | }; | ||
6484 | 6478 | ||
6485 | static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, | 6479 | static int dac960_current_status_proc_show(struct seq_file *m, void *v) |
6486 | int Count, int *EOF, void *Data) | ||
6487 | { | 6480 | { |
6488 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6481 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private; |
6489 | unsigned char *StatusMessage = | 6482 | unsigned char *StatusMessage = |
6490 | "No Rebuild or Consistency Check in Progress\n"; | 6483 | "No Rebuild or Consistency Check in Progress\n"; |
6491 | int ProgressMessageLength = strlen(StatusMessage); | 6484 | int ProgressMessageLength = strlen(StatusMessage); |
6492 | int BytesAvailable; | ||
6493 | if (jiffies != Controller->LastCurrentStatusTime) | 6485 | if (jiffies != Controller->LastCurrentStatusTime) |
6494 | { | 6486 | { |
6495 | Controller->CurrentStatusLength = 0; | 6487 | Controller->CurrentStatusLength = 0; |
@@ -6513,49 +6505,41 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, | |||
6513 | } | 6505 | } |
6514 | Controller->LastCurrentStatusTime = jiffies; | 6506 | Controller->LastCurrentStatusTime = jiffies; |
6515 | } | 6507 | } |
6516 | BytesAvailable = Controller->CurrentStatusLength - Offset; | 6508 | seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer); |
6517 | if (Count >= BytesAvailable) | 6509 | return 0; |
6518 | { | ||
6519 | Count = BytesAvailable; | ||
6520 | *EOF = true; | ||
6521 | } | ||
6522 | if (Count <= 0) return 0; | ||
6523 | *Start = Page; | ||
6524 | memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count); | ||
6525 | return Count; | ||
6526 | } | 6510 | } |
6527 | 6511 | ||
6512 | static int dac960_current_status_proc_open(struct inode *inode, struct file *file) | ||
6513 | { | ||
6514 | return single_open(file, dac960_current_status_proc_show, PDE(inode)->data); | ||
6515 | } | ||
6528 | 6516 | ||
6529 | /* | 6517 | static const struct file_operations dac960_current_status_proc_fops = { |
6530 | DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command. | 6518 | .owner = THIS_MODULE, |
6531 | */ | 6519 | .open = dac960_current_status_proc_open, |
6520 | .read = seq_read, | ||
6521 | .llseek = seq_lseek, | ||
6522 | .release = single_release, | ||
6523 | }; | ||
6532 | 6524 | ||
6533 | static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset, | 6525 | static int dac960_user_command_proc_show(struct seq_file *m, void *v) |
6534 | int Count, int *EOF, void *Data) | ||
6535 | { | 6526 | { |
6536 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6527 | DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private; |
6537 | int BytesAvailable = Controller->UserStatusLength - Offset; | ||
6538 | if (Count >= BytesAvailable) | ||
6539 | { | ||
6540 | Count = BytesAvailable; | ||
6541 | *EOF = true; | ||
6542 | } | ||
6543 | if (Count <= 0) return 0; | ||
6544 | *Start = Page; | ||
6545 | memcpy(Page, &Controller->UserStatusBuffer[Offset], Count); | ||
6546 | return Count; | ||
6547 | } | ||
6548 | 6528 | ||
6529 | seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer); | ||
6530 | return 0; | ||
6531 | } | ||
6549 | 6532 | ||
6550 | /* | 6533 | static int dac960_user_command_proc_open(struct inode *inode, struct file *file) |
6551 | DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command. | 6534 | { |
6552 | */ | 6535 | return single_open(file, dac960_user_command_proc_show, PDE(inode)->data); |
6536 | } | ||
6553 | 6537 | ||
6554 | static int DAC960_ProcWriteUserCommand(struct file *file, | 6538 | static ssize_t dac960_user_command_proc_write(struct file *file, |
6555 | const char __user *Buffer, | 6539 | const char __user *Buffer, |
6556 | unsigned long Count, void *Data) | 6540 | size_t Count, loff_t *pos) |
6557 | { | 6541 | { |
6558 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; | 6542 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data; |
6559 | unsigned char CommandBuffer[80]; | 6543 | unsigned char CommandBuffer[80]; |
6560 | int Length; | 6544 | int Length; |
6561 | if (Count > sizeof(CommandBuffer)-1) return -EINVAL; | 6545 | if (Count > sizeof(CommandBuffer)-1) return -EINVAL; |
@@ -6572,6 +6556,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file, | |||
6572 | ? Count : -EBUSY); | 6556 | ? Count : -EBUSY); |
6573 | } | 6557 | } |
6574 | 6558 | ||
6559 | static const struct file_operations dac960_user_command_proc_fops = { | ||
6560 | .owner = THIS_MODULE, | ||
6561 | .open = dac960_user_command_proc_open, | ||
6562 | .read = seq_read, | ||
6563 | .llseek = seq_lseek, | ||
6564 | .release = single_release, | ||
6565 | .write = dac960_user_command_proc_write, | ||
6566 | }; | ||
6575 | 6567 | ||
6576 | /* | 6568 | /* |
6577 | DAC960_CreateProcEntries creates the /proc/rd/... entries for the | 6569 | DAC960_CreateProcEntries creates the /proc/rd/... entries for the |
@@ -6586,23 +6578,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller) | |||
6586 | 6578 | ||
6587 | if (DAC960_ProcDirectoryEntry == NULL) { | 6579 | if (DAC960_ProcDirectoryEntry == NULL) { |
6588 | DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); | 6580 | DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); |
6589 | StatusProcEntry = create_proc_read_entry("status", 0, | 6581 | StatusProcEntry = proc_create("status", 0, |
6590 | DAC960_ProcDirectoryEntry, | 6582 | DAC960_ProcDirectoryEntry, |
6591 | DAC960_ProcReadStatus, NULL); | 6583 | &dac960_proc_fops); |
6592 | } | 6584 | } |
6593 | 6585 | ||
6594 | sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); | 6586 | sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); |
6595 | ControllerProcEntry = proc_mkdir(Controller->ControllerName, | 6587 | ControllerProcEntry = proc_mkdir(Controller->ControllerName, |
6596 | DAC960_ProcDirectoryEntry); | 6588 | DAC960_ProcDirectoryEntry); |
6597 | create_proc_read_entry("initial_status", 0, ControllerProcEntry, | 6589 | proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller); |
6598 | DAC960_ProcReadInitialStatus, Controller); | 6590 | proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller); |
6599 | create_proc_read_entry("current_status", 0, ControllerProcEntry, | 6591 | UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller); |
6600 | DAC960_ProcReadCurrentStatus, Controller); | ||
6601 | UserCommandProcEntry = | ||
6602 | create_proc_read_entry("user_command", S_IWUSR | S_IRUSR, | ||
6603 | ControllerProcEntry, DAC960_ProcReadUserCommand, | ||
6604 | Controller); | ||
6605 | UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand; | ||
6606 | Controller->ControllerProcEntry = ControllerProcEntry; | 6592 | Controller->ControllerProcEntry = ControllerProcEntry; |
6607 | } | 6593 | } |
6608 | 6594 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 24c3e21ab263..6399e5090df4 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -36,9 +36,11 @@ | |||
36 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/jiffies.h> | ||
39 | #include <linux/hdreg.h> | 40 | #include <linux/hdreg.h> |
40 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
41 | #include <linux/compat.h> | 42 | #include <linux/compat.h> |
43 | #include <linux/mutex.h> | ||
42 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
43 | #include <asm/io.h> | 45 | #include <asm/io.h> |
44 | 46 | ||
@@ -66,6 +68,12 @@ MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | |||
66 | MODULE_VERSION("3.6.20"); | 68 | MODULE_VERSION("3.6.20"); |
67 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
68 | 70 | ||
71 | static int cciss_allow_hpsa; | ||
72 | module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR); | ||
73 | MODULE_PARM_DESC(cciss_allow_hpsa, | ||
74 | "Prevent cciss driver from accessing hardware known to be " | ||
75 | " supported by the hpsa driver"); | ||
76 | |||
69 | #include "cciss_cmd.h" | 77 | #include "cciss_cmd.h" |
70 | #include "cciss.h" | 78 | #include "cciss.h" |
71 | #include <linux/cciss_ioctl.h> | 79 | #include <linux/cciss_ioctl.h> |
@@ -99,8 +107,6 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
99 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | 107 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, |
100 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, | 108 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, |
101 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, | 109 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, |
102 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
103 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
104 | {0,} | 110 | {0,} |
105 | }; | 111 | }; |
106 | 112 | ||
@@ -121,8 +127,6 @@ static struct board_type products[] = { | |||
121 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, | 127 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, |
122 | {0x40910E11, "Smart Array 6i", &SA5_access}, | 128 | {0x40910E11, "Smart Array 6i", &SA5_access}, |
123 | {0x3225103C, "Smart Array P600", &SA5_access}, | 129 | {0x3225103C, "Smart Array P600", &SA5_access}, |
124 | {0x3223103C, "Smart Array P800", &SA5_access}, | ||
125 | {0x3234103C, "Smart Array P400", &SA5_access}, | ||
126 | {0x3235103C, "Smart Array P400i", &SA5_access}, | 130 | {0x3235103C, "Smart Array P400i", &SA5_access}, |
127 | {0x3211103C, "Smart Array E200i", &SA5_access}, | 131 | {0x3211103C, "Smart Array E200i", &SA5_access}, |
128 | {0x3212103C, "Smart Array E200", &SA5_access}, | 132 | {0x3212103C, "Smart Array E200", &SA5_access}, |
@@ -130,6 +134,10 @@ static struct board_type products[] = { | |||
130 | {0x3214103C, "Smart Array E200i", &SA5_access}, | 134 | {0x3214103C, "Smart Array E200i", &SA5_access}, |
131 | {0x3215103C, "Smart Array E200i", &SA5_access}, | 135 | {0x3215103C, "Smart Array E200i", &SA5_access}, |
132 | {0x3237103C, "Smart Array E500", &SA5_access}, | 136 | {0x3237103C, "Smart Array E500", &SA5_access}, |
137 | /* controllers below this line are also supported by the hpsa driver. */ | ||
138 | #define HPSA_BOUNDARY 0x3223103C | ||
139 | {0x3223103C, "Smart Array P800", &SA5_access}, | ||
140 | {0x3234103C, "Smart Array P400", &SA5_access}, | ||
133 | {0x323D103C, "Smart Array P700m", &SA5_access}, | 141 | {0x323D103C, "Smart Array P700m", &SA5_access}, |
134 | {0x3241103C, "Smart Array P212", &SA5_access}, | 142 | {0x3241103C, "Smart Array P212", &SA5_access}, |
135 | {0x3243103C, "Smart Array P410", &SA5_access}, | 143 | {0x3243103C, "Smart Array P410", &SA5_access}, |
@@ -138,7 +146,6 @@ static struct board_type products[] = { | |||
138 | {0x3249103C, "Smart Array P812", &SA5_access}, | 146 | {0x3249103C, "Smart Array P812", &SA5_access}, |
139 | {0x324A103C, "Smart Array P712m", &SA5_access}, | 147 | {0x324A103C, "Smart Array P712m", &SA5_access}, |
140 | {0x324B103C, "Smart Array P711m", &SA5_access}, | 148 | {0x324B103C, "Smart Array P711m", &SA5_access}, |
141 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, | ||
142 | }; | 149 | }; |
143 | 150 | ||
144 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 151 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
@@ -155,6 +162,10 @@ static struct board_type products[] = { | |||
155 | 162 | ||
156 | static ctlr_info_t *hba[MAX_CTLR]; | 163 | static ctlr_info_t *hba[MAX_CTLR]; |
157 | 164 | ||
165 | static struct task_struct *cciss_scan_thread; | ||
166 | static DEFINE_MUTEX(scan_mutex); | ||
167 | static LIST_HEAD(scan_q); | ||
168 | |||
158 | static void do_cciss_request(struct request_queue *q); | 169 | static void do_cciss_request(struct request_queue *q); |
159 | static irqreturn_t do_cciss_intr(int irq, void *dev_id); | 170 | static irqreturn_t do_cciss_intr(int irq, void *dev_id); |
160 | static int cciss_open(struct block_device *bdev, fmode_t mode); | 171 | static int cciss_open(struct block_device *bdev, fmode_t mode); |
@@ -164,9 +175,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
164 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 175 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
165 | 176 | ||
166 | static int cciss_revalidate(struct gendisk *disk); | 177 | static int cciss_revalidate(struct gendisk *disk); |
167 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); | 178 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl); |
168 | static int deregister_disk(ctlr_info_t *h, int drv_index, | 179 | static int deregister_disk(ctlr_info_t *h, int drv_index, |
169 | int clear_all); | 180 | int clear_all, int via_ioctl); |
170 | 181 | ||
171 | static void cciss_read_capacity(int ctlr, int logvol, int withirq, | 182 | static void cciss_read_capacity(int ctlr, int logvol, int withirq, |
172 | sector_t *total_size, unsigned int *block_size); | 183 | sector_t *total_size, unsigned int *block_size); |
@@ -189,8 +200,13 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, | |||
189 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); | 200 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); |
190 | 201 | ||
191 | static void fail_all_cmds(unsigned long ctlr); | 202 | static void fail_all_cmds(unsigned long ctlr); |
203 | static int add_to_scan_list(struct ctlr_info *h); | ||
192 | static int scan_thread(void *data); | 204 | static int scan_thread(void *data); |
193 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); | 205 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); |
206 | static void cciss_hba_release(struct device *dev); | ||
207 | static void cciss_device_release(struct device *dev); | ||
208 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); | ||
209 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); | ||
194 | 210 | ||
195 | #ifdef CONFIG_PROC_FS | 211 | #ifdef CONFIG_PROC_FS |
196 | static void cciss_procinit(int i); | 212 | static void cciss_procinit(int i); |
@@ -245,7 +261,10 @@ static inline void removeQ(CommandList_struct *c) | |||
245 | 261 | ||
246 | #include "cciss_scsi.c" /* For SCSI tape support */ | 262 | #include "cciss_scsi.c" /* For SCSI tape support */ |
247 | 263 | ||
248 | #define RAID_UNKNOWN 6 | 264 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", |
265 | "UNKNOWN" | ||
266 | }; | ||
267 | #define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1) | ||
249 | 268 | ||
250 | #ifdef CONFIG_PROC_FS | 269 | #ifdef CONFIG_PROC_FS |
251 | 270 | ||
@@ -255,9 +274,6 @@ static inline void removeQ(CommandList_struct *c) | |||
255 | #define ENG_GIG 1000000000 | 274 | #define ENG_GIG 1000000000 |
256 | #define ENG_GIG_FACTOR (ENG_GIG/512) | 275 | #define ENG_GIG_FACTOR (ENG_GIG/512) |
257 | #define ENGAGE_SCSI "engage scsi" | 276 | #define ENGAGE_SCSI "engage scsi" |
258 | static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", | ||
259 | "UNKNOWN" | ||
260 | }; | ||
261 | 277 | ||
262 | static struct proc_dir_entry *proc_cciss; | 278 | static struct proc_dir_entry *proc_cciss; |
263 | 279 | ||
@@ -318,7 +334,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) | |||
318 | ctlr_info_t *h = seq->private; | 334 | ctlr_info_t *h = seq->private; |
319 | unsigned ctlr = h->ctlr; | 335 | unsigned ctlr = h->ctlr; |
320 | loff_t *pos = v; | 336 | loff_t *pos = v; |
321 | drive_info_struct *drv = &h->drv[*pos]; | 337 | drive_info_struct *drv = h->drv[*pos]; |
322 | 338 | ||
323 | if (*pos > h->highest_lun) | 339 | if (*pos > h->highest_lun) |
324 | return 0; | 340 | return 0; |
@@ -331,7 +347,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) | |||
331 | vol_sz_frac *= 100; | 347 | vol_sz_frac *= 100; |
332 | sector_div(vol_sz_frac, ENG_GIG_FACTOR); | 348 | sector_div(vol_sz_frac, ENG_GIG_FACTOR); |
333 | 349 | ||
334 | if (drv->raid_level > 5) | 350 | if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN) |
335 | drv->raid_level = RAID_UNKNOWN; | 351 | drv->raid_level = RAID_UNKNOWN; |
336 | seq_printf(seq, "cciss/c%dd%d:" | 352 | seq_printf(seq, "cciss/c%dd%d:" |
337 | "\t%4u.%02uGB\tRAID %s\n", | 353 | "\t%4u.%02uGB\tRAID %s\n", |
@@ -426,7 +442,7 @@ out: | |||
426 | return err; | 442 | return err; |
427 | } | 443 | } |
428 | 444 | ||
429 | static struct file_operations cciss_proc_fops = { | 445 | static const struct file_operations cciss_proc_fops = { |
430 | .owner = THIS_MODULE, | 446 | .owner = THIS_MODULE, |
431 | .open = cciss_seq_open, | 447 | .open = cciss_seq_open, |
432 | .read = seq_read, | 448 | .read = seq_read, |
@@ -454,9 +470,19 @@ static void __devinit cciss_procinit(int i) | |||
454 | #define to_hba(n) container_of(n, struct ctlr_info, dev) | 470 | #define to_hba(n) container_of(n, struct ctlr_info, dev) |
455 | #define to_drv(n) container_of(n, drive_info_struct, dev) | 471 | #define to_drv(n) container_of(n, drive_info_struct, dev) |
456 | 472 | ||
457 | static struct device_type cciss_host_type = { | 473 | static ssize_t host_store_rescan(struct device *dev, |
458 | .name = "cciss_host", | 474 | struct device_attribute *attr, |
459 | }; | 475 | const char *buf, size_t count) |
476 | { | ||
477 | struct ctlr_info *h = to_hba(dev); | ||
478 | |||
479 | add_to_scan_list(h); | ||
480 | wake_up_process(cciss_scan_thread); | ||
481 | wait_for_completion_interruptible(&h->scan_wait); | ||
482 | |||
483 | return count; | ||
484 | } | ||
485 | DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); | ||
460 | 486 | ||
461 | static ssize_t dev_show_unique_id(struct device *dev, | 487 | static ssize_t dev_show_unique_id(struct device *dev, |
462 | struct device_attribute *attr, | 488 | struct device_attribute *attr, |
@@ -560,11 +586,101 @@ static ssize_t dev_show_rev(struct device *dev, | |||
560 | } | 586 | } |
561 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); | 587 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); |
562 | 588 | ||
589 | static ssize_t cciss_show_lunid(struct device *dev, | ||
590 | struct device_attribute *attr, char *buf) | ||
591 | { | ||
592 | drive_info_struct *drv = to_drv(dev); | ||
593 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
594 | unsigned long flags; | ||
595 | unsigned char lunid[8]; | ||
596 | |||
597 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
598 | if (h->busy_configuring) { | ||
599 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
600 | return -EBUSY; | ||
601 | } | ||
602 | if (!drv->heads) { | ||
603 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
604 | return -ENOTTY; | ||
605 | } | ||
606 | memcpy(lunid, drv->LunID, sizeof(lunid)); | ||
607 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
608 | return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
609 | lunid[0], lunid[1], lunid[2], lunid[3], | ||
610 | lunid[4], lunid[5], lunid[6], lunid[7]); | ||
611 | } | ||
612 | DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); | ||
613 | |||
614 | static ssize_t cciss_show_raid_level(struct device *dev, | ||
615 | struct device_attribute *attr, char *buf) | ||
616 | { | ||
617 | drive_info_struct *drv = to_drv(dev); | ||
618 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
619 | int raid; | ||
620 | unsigned long flags; | ||
621 | |||
622 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
623 | if (h->busy_configuring) { | ||
624 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
625 | return -EBUSY; | ||
626 | } | ||
627 | raid = drv->raid_level; | ||
628 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
629 | if (raid < 0 || raid > RAID_UNKNOWN) | ||
630 | raid = RAID_UNKNOWN; | ||
631 | |||
632 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", | ||
633 | raid_label[raid]); | ||
634 | } | ||
635 | DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); | ||
636 | |||
637 | static ssize_t cciss_show_usage_count(struct device *dev, | ||
638 | struct device_attribute *attr, char *buf) | ||
639 | { | ||
640 | drive_info_struct *drv = to_drv(dev); | ||
641 | struct ctlr_info *h = to_hba(drv->dev.parent); | ||
642 | unsigned long flags; | ||
643 | int count; | ||
644 | |||
645 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
646 | if (h->busy_configuring) { | ||
647 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
648 | return -EBUSY; | ||
649 | } | ||
650 | count = drv->usage_count; | ||
651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
652 | return snprintf(buf, 20, "%d\n", count); | ||
653 | } | ||
654 | DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); | ||
655 | |||
656 | static struct attribute *cciss_host_attrs[] = { | ||
657 | &dev_attr_rescan.attr, | ||
658 | NULL | ||
659 | }; | ||
660 | |||
661 | static struct attribute_group cciss_host_attr_group = { | ||
662 | .attrs = cciss_host_attrs, | ||
663 | }; | ||
664 | |||
665 | static const struct attribute_group *cciss_host_attr_groups[] = { | ||
666 | &cciss_host_attr_group, | ||
667 | NULL | ||
668 | }; | ||
669 | |||
670 | static struct device_type cciss_host_type = { | ||
671 | .name = "cciss_host", | ||
672 | .groups = cciss_host_attr_groups, | ||
673 | .release = cciss_hba_release, | ||
674 | }; | ||
675 | |||
563 | static struct attribute *cciss_dev_attrs[] = { | 676 | static struct attribute *cciss_dev_attrs[] = { |
564 | &dev_attr_unique_id.attr, | 677 | &dev_attr_unique_id.attr, |
565 | &dev_attr_model.attr, | 678 | &dev_attr_model.attr, |
566 | &dev_attr_vendor.attr, | 679 | &dev_attr_vendor.attr, |
567 | &dev_attr_rev.attr, | 680 | &dev_attr_rev.attr, |
681 | &dev_attr_lunid.attr, | ||
682 | &dev_attr_raid_level.attr, | ||
683 | &dev_attr_usage_count.attr, | ||
568 | NULL | 684 | NULL |
569 | }; | 685 | }; |
570 | 686 | ||
@@ -580,12 +696,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = { | |||
580 | static struct device_type cciss_dev_type = { | 696 | static struct device_type cciss_dev_type = { |
581 | .name = "cciss_device", | 697 | .name = "cciss_device", |
582 | .groups = cciss_dev_attr_groups, | 698 | .groups = cciss_dev_attr_groups, |
699 | .release = cciss_device_release, | ||
583 | }; | 700 | }; |
584 | 701 | ||
585 | static struct bus_type cciss_bus_type = { | 702 | static struct bus_type cciss_bus_type = { |
586 | .name = "cciss", | 703 | .name = "cciss", |
587 | }; | 704 | }; |
588 | 705 | ||
706 | /* | ||
707 | * cciss_hba_release is called when the reference count | ||
708 | * of h->dev goes to zero. | ||
709 | */ | ||
710 | static void cciss_hba_release(struct device *dev) | ||
711 | { | ||
712 | /* | ||
713 | * nothing to do, but need this to avoid a warning | ||
714 | * about not having a release handler from lib/kref.c. | ||
715 | */ | ||
716 | } | ||
589 | 717 | ||
590 | /* | 718 | /* |
591 | * Initialize sysfs entry for each controller. This sets up and registers | 719 | * Initialize sysfs entry for each controller. This sets up and registers |
@@ -609,6 +737,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) | |||
609 | static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) | 737 | static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) |
610 | { | 738 | { |
611 | device_del(&h->dev); | 739 | device_del(&h->dev); |
740 | put_device(&h->dev); /* final put. */ | ||
741 | } | ||
742 | |||
743 | /* cciss_device_release is called when the reference count | ||
744 | * of h->drv[x]dev goes to zero. | ||
745 | */ | ||
746 | static void cciss_device_release(struct device *dev) | ||
747 | { | ||
748 | drive_info_struct *drv = to_drv(dev); | ||
749 | kfree(drv); | ||
612 | } | 750 | } |
613 | 751 | ||
614 | /* | 752 | /* |
@@ -617,24 +755,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) | |||
617 | * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from | 755 | * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from |
618 | * /sys/block/cciss!c#d# to this entry. | 756 | * /sys/block/cciss!c#d# to this entry. |
619 | */ | 757 | */ |
620 | static int cciss_create_ld_sysfs_entry(struct ctlr_info *h, | 758 | static long cciss_create_ld_sysfs_entry(struct ctlr_info *h, |
621 | drive_info_struct *drv, | ||
622 | int drv_index) | 759 | int drv_index) |
623 | { | 760 | { |
624 | device_initialize(&drv->dev); | 761 | struct device *dev; |
625 | drv->dev.type = &cciss_dev_type; | 762 | |
626 | drv->dev.bus = &cciss_bus_type; | 763 | if (h->drv[drv_index]->device_initialized) |
627 | dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); | 764 | return 0; |
628 | drv->dev.parent = &h->dev; | 765 | |
629 | return device_add(&drv->dev); | 766 | dev = &h->drv[drv_index]->dev; |
767 | device_initialize(dev); | ||
768 | dev->type = &cciss_dev_type; | ||
769 | dev->bus = &cciss_bus_type; | ||
770 | dev_set_name(dev, "c%dd%d", h->ctlr, drv_index); | ||
771 | dev->parent = &h->dev; | ||
772 | h->drv[drv_index]->device_initialized = 1; | ||
773 | return device_add(dev); | ||
630 | } | 774 | } |
631 | 775 | ||
632 | /* | 776 | /* |
633 | * Remove sysfs entries for a logical drive. | 777 | * Remove sysfs entries for a logical drive. |
634 | */ | 778 | */ |
635 | static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) | 779 | static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index, |
780 | int ctlr_exiting) | ||
636 | { | 781 | { |
637 | device_del(&drv->dev); | 782 | struct device *dev = &h->drv[drv_index]->dev; |
783 | |||
784 | /* special case for c*d0, we only destroy it on controller exit */ | ||
785 | if (drv_index == 0 && !ctlr_exiting) | ||
786 | return; | ||
787 | |||
788 | device_del(dev); | ||
789 | put_device(dev); /* the "final" put. */ | ||
790 | h->drv[drv_index] = NULL; | ||
638 | } | 791 | } |
639 | 792 | ||
640 | /* | 793 | /* |
@@ -751,7 +904,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
751 | printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); | 904 | printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); |
752 | #endif /* CCISS_DEBUG */ | 905 | #endif /* CCISS_DEBUG */ |
753 | 906 | ||
754 | if (host->busy_initializing || drv->busy_configuring) | 907 | if (drv->busy_configuring) |
755 | return -EBUSY; | 908 | return -EBUSY; |
756 | /* | 909 | /* |
757 | * Root is allowed to open raw volume zero even if it's not configured | 910 | * Root is allowed to open raw volume zero even if it's not configured |
@@ -767,7 +920,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
767 | if (MINOR(bdev->bd_dev) & 0x0f) { | 920 | if (MINOR(bdev->bd_dev) & 0x0f) { |
768 | return -ENXIO; | 921 | return -ENXIO; |
769 | /* if it is, make sure we have a LUN ID */ | 922 | /* if it is, make sure we have a LUN ID */ |
770 | } else if (drv->LunID == 0) { | 923 | } else if (memcmp(drv->LunID, CTLR_LUNID, |
924 | sizeof(drv->LunID))) { | ||
771 | return -ENXIO; | 925 | return -ENXIO; |
772 | } | 926 | } |
773 | } | 927 | } |
@@ -1132,12 +1286,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1132 | case CCISS_DEREGDISK: | 1286 | case CCISS_DEREGDISK: |
1133 | case CCISS_REGNEWD: | 1287 | case CCISS_REGNEWD: |
1134 | case CCISS_REVALIDVOLS: | 1288 | case CCISS_REVALIDVOLS: |
1135 | return rebuild_lun_table(host, 0); | 1289 | return rebuild_lun_table(host, 0, 1); |
1136 | 1290 | ||
1137 | case CCISS_GETLUNINFO:{ | 1291 | case CCISS_GETLUNINFO:{ |
1138 | LogvolInfo_struct luninfo; | 1292 | LogvolInfo_struct luninfo; |
1139 | 1293 | ||
1140 | luninfo.LunID = drv->LunID; | 1294 | memcpy(&luninfo.LunID, drv->LunID, |
1295 | sizeof(luninfo.LunID)); | ||
1141 | luninfo.num_opens = drv->usage_count; | 1296 | luninfo.num_opens = drv->usage_count; |
1142 | luninfo.num_parts = 0; | 1297 | luninfo.num_parts = 0; |
1143 | if (copy_to_user(argp, &luninfo, | 1298 | if (copy_to_user(argp, &luninfo, |
@@ -1475,7 +1630,10 @@ static void cciss_check_queues(ctlr_info_t *h) | |||
1475 | /* make sure the disk has been added and the drive is real | 1630 | /* make sure the disk has been added and the drive is real |
1476 | * because this can be called from the middle of init_one. | 1631 | * because this can be called from the middle of init_one. |
1477 | */ | 1632 | */ |
1478 | if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) | 1633 | if (!h->drv[curr_queue]) |
1634 | continue; | ||
1635 | if (!(h->drv[curr_queue]->queue) || | ||
1636 | !(h->drv[curr_queue]->heads)) | ||
1479 | continue; | 1637 | continue; |
1480 | blk_start_queue(h->gendisk[curr_queue]->queue); | 1638 | blk_start_queue(h->gendisk[curr_queue]->queue); |
1481 | 1639 | ||
@@ -1532,13 +1690,11 @@ static void cciss_softirq_done(struct request *rq) | |||
1532 | spin_unlock_irqrestore(&h->lock, flags); | 1690 | spin_unlock_irqrestore(&h->lock, flags); |
1533 | } | 1691 | } |
1534 | 1692 | ||
1535 | static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], | 1693 | static inline void log_unit_to_scsi3addr(ctlr_info_t *h, |
1536 | uint32_t log_unit) | 1694 | unsigned char scsi3addr[], uint32_t log_unit) |
1537 | { | 1695 | { |
1538 | log_unit = h->drv[log_unit].LunID & 0x03fff; | 1696 | memcpy(scsi3addr, h->drv[log_unit]->LunID, |
1539 | memset(&scsi3addr[4], 0, 4); | 1697 | sizeof(h->drv[log_unit]->LunID)); |
1540 | memcpy(&scsi3addr[0], &log_unit, 4); | ||
1541 | scsi3addr[3] |= 0x40; | ||
1542 | } | 1698 | } |
1543 | 1699 | ||
1544 | /* This function gets the SCSI vendor, model, and revision of a logical drive | 1700 | /* This function gets the SCSI vendor, model, and revision of a logical drive |
@@ -1615,16 +1771,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
1615 | return; | 1771 | return; |
1616 | } | 1772 | } |
1617 | 1773 | ||
1618 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | 1774 | /* |
1775 | * cciss_add_disk sets up the block device queue for a logical drive | ||
1776 | */ | ||
1777 | static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
1619 | int drv_index) | 1778 | int drv_index) |
1620 | { | 1779 | { |
1621 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1780 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); |
1781 | if (!disk->queue) | ||
1782 | goto init_queue_failure; | ||
1622 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | 1783 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); |
1623 | disk->major = h->major; | 1784 | disk->major = h->major; |
1624 | disk->first_minor = drv_index << NWD_SHIFT; | 1785 | disk->first_minor = drv_index << NWD_SHIFT; |
1625 | disk->fops = &cciss_fops; | 1786 | disk->fops = &cciss_fops; |
1626 | disk->private_data = &h->drv[drv_index]; | 1787 | if (cciss_create_ld_sysfs_entry(h, drv_index)) |
1627 | disk->driverfs_dev = &h->drv[drv_index].dev; | 1788 | goto cleanup_queue; |
1789 | disk->private_data = h->drv[drv_index]; | ||
1790 | disk->driverfs_dev = &h->drv[drv_index]->dev; | ||
1628 | 1791 | ||
1629 | /* Set up queue information */ | 1792 | /* Set up queue information */ |
1630 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | 1793 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); |
@@ -1642,14 +1805,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
1642 | disk->queue->queuedata = h; | 1805 | disk->queue->queuedata = h; |
1643 | 1806 | ||
1644 | blk_queue_logical_block_size(disk->queue, | 1807 | blk_queue_logical_block_size(disk->queue, |
1645 | h->drv[drv_index].block_size); | 1808 | h->drv[drv_index]->block_size); |
1646 | 1809 | ||
1647 | /* Make sure all queue data is written out before */ | 1810 | /* Make sure all queue data is written out before */ |
1648 | /* setting h->drv[drv_index].queue, as setting this */ | 1811 | /* setting h->drv[drv_index]->queue, as setting this */ |
1649 | /* allows the interrupt handler to start the queue */ | 1812 | /* allows the interrupt handler to start the queue */ |
1650 | wmb(); | 1813 | wmb(); |
1651 | h->drv[drv_index].queue = disk->queue; | 1814 | h->drv[drv_index]->queue = disk->queue; |
1652 | add_disk(disk); | 1815 | add_disk(disk); |
1816 | return 0; | ||
1817 | |||
1818 | cleanup_queue: | ||
1819 | blk_cleanup_queue(disk->queue); | ||
1820 | disk->queue = NULL; | ||
1821 | init_queue_failure: | ||
1822 | return -1; | ||
1653 | } | 1823 | } |
1654 | 1824 | ||
1655 | /* This function will check the usage_count of the drive to be updated/added. | 1825 | /* This function will check the usage_count of the drive to be updated/added. |
@@ -1662,7 +1832,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
1662 | * is also the controller node. Any changes to disk 0 will show up on | 1832 | * is also the controller node. Any changes to disk 0 will show up on |
1663 | * the next reboot. | 1833 | * the next reboot. |
1664 | */ | 1834 | */ |
1665 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | 1835 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, |
1836 | int via_ioctl) | ||
1666 | { | 1837 | { |
1667 | ctlr_info_t *h = hba[ctlr]; | 1838 | ctlr_info_t *h = hba[ctlr]; |
1668 | struct gendisk *disk; | 1839 | struct gendisk *disk; |
@@ -1672,21 +1843,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1672 | unsigned long flags = 0; | 1843 | unsigned long flags = 0; |
1673 | int ret = 0; | 1844 | int ret = 0; |
1674 | drive_info_struct *drvinfo; | 1845 | drive_info_struct *drvinfo; |
1675 | int was_only_controller_node; | ||
1676 | 1846 | ||
1677 | /* Get information about the disk and modify the driver structure */ | 1847 | /* Get information about the disk and modify the driver structure */ |
1678 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1848 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
1679 | drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); | 1849 | drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL); |
1680 | if (inq_buff == NULL || drvinfo == NULL) | 1850 | if (inq_buff == NULL || drvinfo == NULL) |
1681 | goto mem_msg; | 1851 | goto mem_msg; |
1682 | 1852 | ||
1683 | /* See if we're trying to update the "controller node" | ||
1684 | * this will happen the when the first logical drive gets | ||
1685 | * created by ACU. | ||
1686 | */ | ||
1687 | was_only_controller_node = (drv_index == 0 && | ||
1688 | h->drv[0].raid_level == -1); | ||
1689 | |||
1690 | /* testing to see if 16-byte CDBs are already being used */ | 1853 | /* testing to see if 16-byte CDBs are already being used */ |
1691 | if (h->cciss_read == CCISS_READ_16) { | 1854 | if (h->cciss_read == CCISS_READ_16) { |
1692 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1855 | cciss_read_capacity_16(h->ctlr, drv_index, 1, |
@@ -1719,16 +1882,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1719 | drvinfo->model, drvinfo->rev); | 1882 | drvinfo->model, drvinfo->rev); |
1720 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | 1883 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, |
1721 | sizeof(drvinfo->serial_no)); | 1884 | sizeof(drvinfo->serial_no)); |
1885 | /* Save the lunid in case we deregister the disk, below. */ | ||
1886 | memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, | ||
1887 | sizeof(drvinfo->LunID)); | ||
1722 | 1888 | ||
1723 | /* Is it the same disk we already know, and nothing's changed? */ | 1889 | /* Is it the same disk we already know, and nothing's changed? */ |
1724 | if (h->drv[drv_index].raid_level != -1 && | 1890 | if (h->drv[drv_index]->raid_level != -1 && |
1725 | ((memcmp(drvinfo->serial_no, | 1891 | ((memcmp(drvinfo->serial_no, |
1726 | h->drv[drv_index].serial_no, 16) == 0) && | 1892 | h->drv[drv_index]->serial_no, 16) == 0) && |
1727 | drvinfo->block_size == h->drv[drv_index].block_size && | 1893 | drvinfo->block_size == h->drv[drv_index]->block_size && |
1728 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | 1894 | drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks && |
1729 | drvinfo->heads == h->drv[drv_index].heads && | 1895 | drvinfo->heads == h->drv[drv_index]->heads && |
1730 | drvinfo->sectors == h->drv[drv_index].sectors && | 1896 | drvinfo->sectors == h->drv[drv_index]->sectors && |
1731 | drvinfo->cylinders == h->drv[drv_index].cylinders)) | 1897 | drvinfo->cylinders == h->drv[drv_index]->cylinders)) |
1732 | /* The disk is unchanged, nothing to update */ | 1898 | /* The disk is unchanged, nothing to update */ |
1733 | goto freeret; | 1899 | goto freeret; |
1734 | 1900 | ||
@@ -1738,18 +1904,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1738 | * If the disk already exists then deregister it before proceeding | 1904 | * If the disk already exists then deregister it before proceeding |
1739 | * (unless it's the first disk (for the controller node). | 1905 | * (unless it's the first disk (for the controller node). |
1740 | */ | 1906 | */ |
1741 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | 1907 | if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { |
1742 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | 1908 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); |
1743 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1909 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1744 | h->drv[drv_index].busy_configuring = 1; | 1910 | h->drv[drv_index]->busy_configuring = 1; |
1745 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1911 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1746 | 1912 | ||
1747 | /* deregister_disk sets h->drv[drv_index].queue = NULL | 1913 | /* deregister_disk sets h->drv[drv_index]->queue = NULL |
1748 | * which keeps the interrupt handler from starting | 1914 | * which keeps the interrupt handler from starting |
1749 | * the queue. | 1915 | * the queue. |
1750 | */ | 1916 | */ |
1751 | ret = deregister_disk(h, drv_index, 0); | 1917 | ret = deregister_disk(h, drv_index, 0, via_ioctl); |
1752 | h->drv[drv_index].busy_configuring = 0; | ||
1753 | } | 1918 | } |
1754 | 1919 | ||
1755 | /* If the disk is in use return */ | 1920 | /* If the disk is in use return */ |
@@ -1757,22 +1922,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1757 | goto freeret; | 1922 | goto freeret; |
1758 | 1923 | ||
1759 | /* Save the new information from cciss_geometry_inquiry | 1924 | /* Save the new information from cciss_geometry_inquiry |
1760 | * and serial number inquiry. | 1925 | * and serial number inquiry. If the disk was deregistered |
1926 | * above, then h->drv[drv_index] will be NULL. | ||
1761 | */ | 1927 | */ |
1762 | h->drv[drv_index].block_size = drvinfo->block_size; | 1928 | if (h->drv[drv_index] == NULL) { |
1763 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | 1929 | drvinfo->device_initialized = 0; |
1764 | h->drv[drv_index].heads = drvinfo->heads; | 1930 | h->drv[drv_index] = drvinfo; |
1765 | h->drv[drv_index].sectors = drvinfo->sectors; | 1931 | drvinfo = NULL; /* so it won't be freed below. */ |
1766 | h->drv[drv_index].cylinders = drvinfo->cylinders; | 1932 | } else { |
1767 | h->drv[drv_index].raid_level = drvinfo->raid_level; | 1933 | /* special case for cxd0 */ |
1768 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); | 1934 | h->drv[drv_index]->block_size = drvinfo->block_size; |
1769 | memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1); | 1935 | h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks; |
1770 | memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1); | 1936 | h->drv[drv_index]->heads = drvinfo->heads; |
1771 | memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1); | 1937 | h->drv[drv_index]->sectors = drvinfo->sectors; |
1938 | h->drv[drv_index]->cylinders = drvinfo->cylinders; | ||
1939 | h->drv[drv_index]->raid_level = drvinfo->raid_level; | ||
1940 | memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16); | ||
1941 | memcpy(h->drv[drv_index]->vendor, drvinfo->vendor, | ||
1942 | VENDOR_LEN + 1); | ||
1943 | memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1); | ||
1944 | memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1); | ||
1945 | } | ||
1772 | 1946 | ||
1773 | ++h->num_luns; | 1947 | ++h->num_luns; |
1774 | disk = h->gendisk[drv_index]; | 1948 | disk = h->gendisk[drv_index]; |
1775 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1949 | set_capacity(disk, h->drv[drv_index]->nr_blocks); |
1776 | 1950 | ||
1777 | /* If it's not disk 0 (drv_index != 0) | 1951 | /* If it's not disk 0 (drv_index != 0) |
1778 | * or if it was disk 0, but there was previously | 1952 | * or if it was disk 0, but there was previously |
@@ -1780,8 +1954,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) | |||
1780 | * (raid_leve == -1) then we want to update the | 1954 | * (raid_leve == -1) then we want to update the |
1781 | * logical drive's information. | 1955 | * logical drive's information. |
1782 | */ | 1956 | */ |
1783 | if (drv_index || first_time) | 1957 | if (drv_index || first_time) { |
1784 | cciss_add_disk(h, disk, drv_index); | 1958 | if (cciss_add_disk(h, disk, drv_index) != 0) { |
1959 | cciss_free_gendisk(h, drv_index); | ||
1960 | cciss_free_drive_info(h, drv_index); | ||
1961 | printk(KERN_WARNING "cciss:%d could not update " | ||
1962 | "disk %d\n", h->ctlr, drv_index); | ||
1963 | --h->num_luns; | ||
1964 | } | ||
1965 | } | ||
1785 | 1966 | ||
1786 | freeret: | 1967 | freeret: |
1787 | kfree(inq_buff); | 1968 | kfree(inq_buff); |
@@ -1793,28 +1974,70 @@ mem_msg: | |||
1793 | } | 1974 | } |
1794 | 1975 | ||
1795 | /* This function will find the first index of the controllers drive array | 1976 | /* This function will find the first index of the controllers drive array |
1796 | * that has a -1 for the raid_level and will return that index. This is | 1977 | * that has a null drv pointer and allocate the drive info struct and |
1797 | * where new drives will be added. If the index to be returned is greater | 1978 | * will return that index This is where new drives will be added. |
1798 | * than the highest_lun index for the controller then highest_lun is set | 1979 | * If the index to be returned is greater than the highest_lun index for |
1799 | * to this new index. If there are no available indexes then -1 is returned. | 1980 | * the controller then highest_lun is set * to this new index. |
1800 | * "controller_node" is used to know if this is a real logical drive, or just | 1981 | * If there are no available indexes or if tha allocation fails, then -1 |
1801 | * the controller node, which determines if this counts towards highest_lun. | 1982 | * is returned. * "controller_node" is used to know if this is a real |
1983 | * logical drive, or just the controller node, which determines if this | ||
1984 | * counts towards highest_lun. | ||
1802 | */ | 1985 | */ |
1803 | static int cciss_find_free_drive_index(int ctlr, int controller_node) | 1986 | static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node) |
1804 | { | 1987 | { |
1805 | int i; | 1988 | int i; |
1989 | drive_info_struct *drv; | ||
1806 | 1990 | ||
1991 | /* Search for an empty slot for our drive info */ | ||
1807 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1992 | for (i = 0; i < CISS_MAX_LUN; i++) { |
1808 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1993 | |
1809 | if (i > hba[ctlr]->highest_lun) | 1994 | /* if not cxd0 case, and it's occupied, skip it. */ |
1810 | if (!controller_node) | 1995 | if (h->drv[i] && i != 0) |
1811 | hba[ctlr]->highest_lun = i; | 1996 | continue; |
1997 | /* | ||
1998 | * If it's cxd0 case, and drv is alloc'ed already, and a | ||
1999 | * disk is configured there, skip it. | ||
2000 | */ | ||
2001 | if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1) | ||
2002 | continue; | ||
2003 | |||
2004 | /* | ||
2005 | * We've found an empty slot. Update highest_lun | ||
2006 | * provided this isn't just the fake cxd0 controller node. | ||
2007 | */ | ||
2008 | if (i > h->highest_lun && !controller_node) | ||
2009 | h->highest_lun = i; | ||
2010 | |||
2011 | /* If adding a real disk at cxd0, and it's already alloc'ed */ | ||
2012 | if (i == 0 && h->drv[i] != NULL) | ||
1812 | return i; | 2013 | return i; |
1813 | } | 2014 | |
2015 | /* | ||
2016 | * Found an empty slot, not already alloc'ed. Allocate it. | ||
2017 | * Mark it with raid_level == -1, so we know it's new later on. | ||
2018 | */ | ||
2019 | drv = kzalloc(sizeof(*drv), GFP_KERNEL); | ||
2020 | if (!drv) | ||
2021 | return -1; | ||
2022 | drv->raid_level = -1; /* so we know it's new */ | ||
2023 | h->drv[i] = drv; | ||
2024 | return i; | ||
1814 | } | 2025 | } |
1815 | return -1; | 2026 | return -1; |
1816 | } | 2027 | } |
1817 | 2028 | ||
2029 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index) | ||
2030 | { | ||
2031 | kfree(h->drv[drv_index]); | ||
2032 | h->drv[drv_index] = NULL; | ||
2033 | } | ||
2034 | |||
2035 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index) | ||
2036 | { | ||
2037 | put_disk(h->gendisk[drv_index]); | ||
2038 | h->gendisk[drv_index] = NULL; | ||
2039 | } | ||
2040 | |||
1818 | /* cciss_add_gendisk finds a free hba[]->drv structure | 2041 | /* cciss_add_gendisk finds a free hba[]->drv structure |
1819 | * and allocates a gendisk if needed, and sets the lunid | 2042 | * and allocates a gendisk if needed, and sets the lunid |
1820 | * in the drvinfo structure. It returns the index into | 2043 | * in the drvinfo structure. It returns the index into |
@@ -1824,13 +2047,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node) | |||
1824 | * a means to talk to the controller in case no logical | 2047 | * a means to talk to the controller in case no logical |
1825 | * drives have yet been configured. | 2048 | * drives have yet been configured. |
1826 | */ | 2049 | */ |
1827 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | 2050 | static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], |
2051 | int controller_node) | ||
1828 | { | 2052 | { |
1829 | int drv_index; | 2053 | int drv_index; |
1830 | 2054 | ||
1831 | drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); | 2055 | drv_index = cciss_alloc_drive_info(h, controller_node); |
1832 | if (drv_index == -1) | 2056 | if (drv_index == -1) |
1833 | return -1; | 2057 | return -1; |
2058 | |||
1834 | /*Check if the gendisk needs to be allocated */ | 2059 | /*Check if the gendisk needs to be allocated */ |
1835 | if (!h->gendisk[drv_index]) { | 2060 | if (!h->gendisk[drv_index]) { |
1836 | h->gendisk[drv_index] = | 2061 | h->gendisk[drv_index] = |
@@ -1839,23 +2064,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | |||
1839 | printk(KERN_ERR "cciss%d: could not " | 2064 | printk(KERN_ERR "cciss%d: could not " |
1840 | "allocate a new disk %d\n", | 2065 | "allocate a new disk %d\n", |
1841 | h->ctlr, drv_index); | 2066 | h->ctlr, drv_index); |
1842 | return -1; | 2067 | goto err_free_drive_info; |
1843 | } | 2068 | } |
1844 | } | 2069 | } |
1845 | h->drv[drv_index].LunID = lunid; | 2070 | memcpy(h->drv[drv_index]->LunID, lunid, |
1846 | if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) | 2071 | sizeof(h->drv[drv_index]->LunID)); |
2072 | if (cciss_create_ld_sysfs_entry(h, drv_index)) | ||
1847 | goto err_free_disk; | 2073 | goto err_free_disk; |
1848 | |||
1849 | /* Don't need to mark this busy because nobody */ | 2074 | /* Don't need to mark this busy because nobody */ |
1850 | /* else knows about this disk yet to contend */ | 2075 | /* else knows about this disk yet to contend */ |
1851 | /* for access to it. */ | 2076 | /* for access to it. */ |
1852 | h->drv[drv_index].busy_configuring = 0; | 2077 | h->drv[drv_index]->busy_configuring = 0; |
1853 | wmb(); | 2078 | wmb(); |
1854 | return drv_index; | 2079 | return drv_index; |
1855 | 2080 | ||
1856 | err_free_disk: | 2081 | err_free_disk: |
1857 | put_disk(h->gendisk[drv_index]); | 2082 | cciss_free_gendisk(h, drv_index); |
1858 | h->gendisk[drv_index] = NULL; | 2083 | err_free_drive_info: |
2084 | cciss_free_drive_info(h, drv_index); | ||
1859 | return -1; | 2085 | return -1; |
1860 | } | 2086 | } |
1861 | 2087 | ||
@@ -1872,21 +2098,25 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
1872 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | 2098 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ |
1873 | return; | 2099 | return; |
1874 | 2100 | ||
1875 | drv_index = cciss_add_gendisk(h, 0, 1); | 2101 | drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1); |
1876 | if (drv_index == -1) { | 2102 | if (drv_index == -1) |
1877 | printk(KERN_WARNING "cciss%d: could not " | 2103 | goto error; |
1878 | "add disk 0.\n", h->ctlr); | 2104 | h->drv[drv_index]->block_size = 512; |
1879 | return; | 2105 | h->drv[drv_index]->nr_blocks = 0; |
1880 | } | 2106 | h->drv[drv_index]->heads = 0; |
1881 | h->drv[drv_index].block_size = 512; | 2107 | h->drv[drv_index]->sectors = 0; |
1882 | h->drv[drv_index].nr_blocks = 0; | 2108 | h->drv[drv_index]->cylinders = 0; |
1883 | h->drv[drv_index].heads = 0; | 2109 | h->drv[drv_index]->raid_level = -1; |
1884 | h->drv[drv_index].sectors = 0; | 2110 | memset(h->drv[drv_index]->serial_no, 0, 16); |
1885 | h->drv[drv_index].cylinders = 0; | ||
1886 | h->drv[drv_index].raid_level = -1; | ||
1887 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
1888 | disk = h->gendisk[drv_index]; | 2111 | disk = h->gendisk[drv_index]; |
1889 | cciss_add_disk(h, disk, drv_index); | 2112 | if (cciss_add_disk(h, disk, drv_index) == 0) |
2113 | return; | ||
2114 | cciss_free_gendisk(h, drv_index); | ||
2115 | cciss_free_drive_info(h, drv_index); | ||
2116 | error: | ||
2117 | printk(KERN_WARNING "cciss%d: could not " | ||
2118 | "add disk 0.\n", h->ctlr); | ||
2119 | return; | ||
1890 | } | 2120 | } |
1891 | 2121 | ||
1892 | /* This function will add and remove logical drives from the Logical | 2122 | /* This function will add and remove logical drives from the Logical |
@@ -1897,7 +2127,8 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
1897 | * INPUT | 2127 | * INPUT |
1898 | * h = The controller to perform the operations on | 2128 | * h = The controller to perform the operations on |
1899 | */ | 2129 | */ |
1900 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) | 2130 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, |
2131 | int via_ioctl) | ||
1901 | { | 2132 | { |
1902 | int ctlr = h->ctlr; | 2133 | int ctlr = h->ctlr; |
1903 | int num_luns; | 2134 | int num_luns; |
@@ -1907,7 +2138,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
1907 | int i; | 2138 | int i; |
1908 | int drv_found; | 2139 | int drv_found; |
1909 | int drv_index = 0; | 2140 | int drv_index = 0; |
1910 | __u32 lunid = 0; | 2141 | unsigned char lunid[8] = CTLR_LUNID; |
1911 | unsigned long flags; | 2142 | unsigned long flags; |
1912 | 2143 | ||
1913 | if (!capable(CAP_SYS_RAWIO)) | 2144 | if (!capable(CAP_SYS_RAWIO)) |
@@ -1960,13 +2191,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
1960 | drv_found = 0; | 2191 | drv_found = 0; |
1961 | 2192 | ||
1962 | /* skip holes in the array from already deleted drives */ | 2193 | /* skip holes in the array from already deleted drives */ |
1963 | if (h->drv[i].raid_level == -1) | 2194 | if (h->drv[i] == NULL) |
1964 | continue; | 2195 | continue; |
1965 | 2196 | ||
1966 | for (j = 0; j < num_luns; j++) { | 2197 | for (j = 0; j < num_luns; j++) { |
1967 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | 2198 | memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid)); |
1968 | lunid = le32_to_cpu(lunid); | 2199 | if (memcmp(h->drv[i]->LunID, lunid, |
1969 | if (h->drv[i].LunID == lunid) { | 2200 | sizeof(lunid)) == 0) { |
1970 | drv_found = 1; | 2201 | drv_found = 1; |
1971 | break; | 2202 | break; |
1972 | } | 2203 | } |
@@ -1974,11 +2205,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
1974 | if (!drv_found) { | 2205 | if (!drv_found) { |
1975 | /* Deregister it from the OS, it's gone. */ | 2206 | /* Deregister it from the OS, it's gone. */ |
1976 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 2207 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1977 | h->drv[i].busy_configuring = 1; | 2208 | h->drv[i]->busy_configuring = 1; |
1978 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2209 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1979 | return_code = deregister_disk(h, i, 1); | 2210 | return_code = deregister_disk(h, i, 1, via_ioctl); |
1980 | cciss_destroy_ld_sysfs_entry(&h->drv[i]); | 2211 | if (h->drv[i] != NULL) |
1981 | h->drv[i].busy_configuring = 0; | 2212 | h->drv[i]->busy_configuring = 0; |
1982 | } | 2213 | } |
1983 | } | 2214 | } |
1984 | 2215 | ||
@@ -1992,17 +2223,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
1992 | 2223 | ||
1993 | drv_found = 0; | 2224 | drv_found = 0; |
1994 | 2225 | ||
1995 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); | 2226 | memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid)); |
1996 | lunid = le32_to_cpu(lunid); | ||
1997 | |||
1998 | /* Find if the LUN is already in the drive array | 2227 | /* Find if the LUN is already in the drive array |
1999 | * of the driver. If so then update its info | 2228 | * of the driver. If so then update its info |
2000 | * if not in use. If it does not exist then find | 2229 | * if not in use. If it does not exist then find |
2001 | * the first free index and add it. | 2230 | * the first free index and add it. |
2002 | */ | 2231 | */ |
2003 | for (j = 0; j <= h->highest_lun; j++) { | 2232 | for (j = 0; j <= h->highest_lun; j++) { |
2004 | if (h->drv[j].raid_level != -1 && | 2233 | if (h->drv[j] != NULL && |
2005 | h->drv[j].LunID == lunid) { | 2234 | memcmp(h->drv[j]->LunID, lunid, |
2235 | sizeof(h->drv[j]->LunID)) == 0) { | ||
2006 | drv_index = j; | 2236 | drv_index = j; |
2007 | drv_found = 1; | 2237 | drv_found = 1; |
2008 | break; | 2238 | break; |
@@ -2015,7 +2245,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) | |||
2015 | if (drv_index == -1) | 2245 | if (drv_index == -1) |
2016 | goto freeret; | 2246 | goto freeret; |
2017 | } | 2247 | } |
2018 | cciss_update_drive_info(ctlr, drv_index, first_time); | 2248 | cciss_update_drive_info(ctlr, drv_index, first_time, |
2249 | via_ioctl); | ||
2019 | } /* end for */ | 2250 | } /* end for */ |
2020 | 2251 | ||
2021 | freeret: | 2252 | freeret: |
@@ -2032,6 +2263,25 @@ mem_msg: | |||
2032 | goto freeret; | 2263 | goto freeret; |
2033 | } | 2264 | } |
2034 | 2265 | ||
2266 | static void cciss_clear_drive_info(drive_info_struct *drive_info) | ||
2267 | { | ||
2268 | /* zero out the disk size info */ | ||
2269 | drive_info->nr_blocks = 0; | ||
2270 | drive_info->block_size = 0; | ||
2271 | drive_info->heads = 0; | ||
2272 | drive_info->sectors = 0; | ||
2273 | drive_info->cylinders = 0; | ||
2274 | drive_info->raid_level = -1; | ||
2275 | memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no)); | ||
2276 | memset(drive_info->model, 0, sizeof(drive_info->model)); | ||
2277 | memset(drive_info->rev, 0, sizeof(drive_info->rev)); | ||
2278 | memset(drive_info->vendor, 0, sizeof(drive_info->vendor)); | ||
2279 | /* | ||
2280 | * don't clear the LUNID though, we need to remember which | ||
2281 | * one this one is. | ||
2282 | */ | ||
2283 | } | ||
2284 | |||
2035 | /* This function will deregister the disk and it's queue from the | 2285 | /* This function will deregister the disk and it's queue from the |
2036 | * kernel. It must be called with the controller lock held and the | 2286 | * kernel. It must be called with the controller lock held and the |
2037 | * drv structures busy_configuring flag set. It's parameters are: | 2287 | * drv structures busy_configuring flag set. It's parameters are: |
@@ -2046,43 +2296,48 @@ mem_msg: | |||
2046 | * the disk in preparation for re-adding it. In this case | 2296 | * the disk in preparation for re-adding it. In this case |
2047 | * the highest_lun should be left unchanged and the LunID | 2297 | * the highest_lun should be left unchanged and the LunID |
2048 | * should not be cleared. | 2298 | * should not be cleared. |
2299 | * via_ioctl | ||
2300 | * This indicates whether we've reached this path via ioctl. | ||
2301 | * This affects the maximum usage count allowed for c0d0 to be messed with. | ||
2302 | * If this path is reached via ioctl(), then the max_usage_count will | ||
2303 | * be 1, as the process calling ioctl() has got to have the device open. | ||
2304 | * If we get here via sysfs, then the max usage count will be zero. | ||
2049 | */ | 2305 | */ |
2050 | static int deregister_disk(ctlr_info_t *h, int drv_index, | 2306 | static int deregister_disk(ctlr_info_t *h, int drv_index, |
2051 | int clear_all) | 2307 | int clear_all, int via_ioctl) |
2052 | { | 2308 | { |
2053 | int i; | 2309 | int i; |
2054 | struct gendisk *disk; | 2310 | struct gendisk *disk; |
2055 | drive_info_struct *drv; | 2311 | drive_info_struct *drv; |
2312 | int recalculate_highest_lun; | ||
2056 | 2313 | ||
2057 | if (!capable(CAP_SYS_RAWIO)) | 2314 | if (!capable(CAP_SYS_RAWIO)) |
2058 | return -EPERM; | 2315 | return -EPERM; |
2059 | 2316 | ||
2060 | drv = &h->drv[drv_index]; | 2317 | drv = h->drv[drv_index]; |
2061 | disk = h->gendisk[drv_index]; | 2318 | disk = h->gendisk[drv_index]; |
2062 | 2319 | ||
2063 | /* make sure logical volume is NOT is use */ | 2320 | /* make sure logical volume is NOT is use */ |
2064 | if (clear_all || (h->gendisk[0] == disk)) { | 2321 | if (clear_all || (h->gendisk[0] == disk)) { |
2065 | if (drv->usage_count > 1) | 2322 | if (drv->usage_count > via_ioctl) |
2066 | return -EBUSY; | 2323 | return -EBUSY; |
2067 | } else if (drv->usage_count > 0) | 2324 | } else if (drv->usage_count > 0) |
2068 | return -EBUSY; | 2325 | return -EBUSY; |
2069 | 2326 | ||
2327 | recalculate_highest_lun = (drv == h->drv[h->highest_lun]); | ||
2328 | |||
2070 | /* invalidate the devices and deregister the disk. If it is disk | 2329 | /* invalidate the devices and deregister the disk. If it is disk |
2071 | * zero do not deregister it but just zero out it's values. This | 2330 | * zero do not deregister it but just zero out it's values. This |
2072 | * allows us to delete disk zero but keep the controller registered. | 2331 | * allows us to delete disk zero but keep the controller registered. |
2073 | */ | 2332 | */ |
2074 | if (h->gendisk[0] != disk) { | 2333 | if (h->gendisk[0] != disk) { |
2075 | struct request_queue *q = disk->queue; | 2334 | struct request_queue *q = disk->queue; |
2076 | if (disk->flags & GENHD_FL_UP) | 2335 | if (disk->flags & GENHD_FL_UP) { |
2336 | cciss_destroy_ld_sysfs_entry(h, drv_index, 0); | ||
2077 | del_gendisk(disk); | 2337 | del_gendisk(disk); |
2078 | if (q) { | ||
2079 | blk_cleanup_queue(q); | ||
2080 | /* Set drv->queue to NULL so that we do not try | ||
2081 | * to call blk_start_queue on this queue in the | ||
2082 | * interrupt handler | ||
2083 | */ | ||
2084 | drv->queue = NULL; | ||
2085 | } | 2338 | } |
2339 | if (q) | ||
2340 | blk_cleanup_queue(q); | ||
2086 | /* If clear_all is set then we are deleting the logical | 2341 | /* If clear_all is set then we are deleting the logical |
2087 | * drive, not just refreshing its info. For drives | 2342 | * drive, not just refreshing its info. For drives |
2088 | * other than disk 0 we will call put_disk. We do not | 2343 | * other than disk 0 we will call put_disk. We do not |
@@ -2105,34 +2360,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, | |||
2105 | } | 2360 | } |
2106 | } else { | 2361 | } else { |
2107 | set_capacity(disk, 0); | 2362 | set_capacity(disk, 0); |
2363 | cciss_clear_drive_info(drv); | ||
2108 | } | 2364 | } |
2109 | 2365 | ||
2110 | --h->num_luns; | 2366 | --h->num_luns; |
2111 | /* zero out the disk size info */ | ||
2112 | drv->nr_blocks = 0; | ||
2113 | drv->block_size = 0; | ||
2114 | drv->heads = 0; | ||
2115 | drv->sectors = 0; | ||
2116 | drv->cylinders = 0; | ||
2117 | drv->raid_level = -1; /* This can be used as a flag variable to | ||
2118 | * indicate that this element of the drive | ||
2119 | * array is free. | ||
2120 | */ | ||
2121 | |||
2122 | if (clear_all) { | ||
2123 | /* check to see if it was the last disk */ | ||
2124 | if (drv == h->drv + h->highest_lun) { | ||
2125 | /* if so, find the new hightest lun */ | ||
2126 | int i, newhighest = -1; | ||
2127 | for (i = 0; i <= h->highest_lun; i++) { | ||
2128 | /* if the disk has size > 0, it is available */ | ||
2129 | if (h->drv[i].heads) | ||
2130 | newhighest = i; | ||
2131 | } | ||
2132 | h->highest_lun = newhighest; | ||
2133 | } | ||
2134 | 2367 | ||
2135 | drv->LunID = 0; | 2368 | /* if it was the last disk, find the new hightest lun */ |
2369 | if (clear_all && recalculate_highest_lun) { | ||
2370 | int i, newhighest = -1; | ||
2371 | for (i = 0; i <= h->highest_lun; i++) { | ||
2372 | /* if the disk has size > 0, it is available */ | ||
2373 | if (h->drv[i] && h->drv[i]->heads) | ||
2374 | newhighest = i; | ||
2375 | } | ||
2376 | h->highest_lun = newhighest; | ||
2136 | } | 2377 | } |
2137 | return 0; | 2378 | return 0; |
2138 | } | 2379 | } |
@@ -2479,8 +2720,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
2479 | } else { /* Get geometry failed */ | 2720 | } else { /* Get geometry failed */ |
2480 | printk(KERN_WARNING "cciss: reading geometry failed\n"); | 2721 | printk(KERN_WARNING "cciss: reading geometry failed\n"); |
2481 | } | 2722 | } |
2482 | printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n", | ||
2483 | drv->heads, drv->sectors, drv->cylinders); | ||
2484 | } | 2723 | } |
2485 | 2724 | ||
2486 | static void | 2725 | static void |
@@ -2514,9 +2753,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, | |||
2514 | *total_size = 0; | 2753 | *total_size = 0; |
2515 | *block_size = BLOCK_SIZE; | 2754 | *block_size = BLOCK_SIZE; |
2516 | } | 2755 | } |
2517 | if (*total_size != 0) | ||
2518 | printk(KERN_INFO " blocks= %llu block_size= %d\n", | ||
2519 | (unsigned long long)*total_size+1, *block_size); | ||
2520 | kfree(buf); | 2756 | kfree(buf); |
2521 | } | 2757 | } |
2522 | 2758 | ||
@@ -2568,7 +2804,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
2568 | InquiryData_struct *inq_buff = NULL; | 2804 | InquiryData_struct *inq_buff = NULL; |
2569 | 2805 | ||
2570 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2806 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
2571 | if (h->drv[logvol].LunID == drv->LunID) { | 2807 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
2808 | sizeof(drv->LunID)) == 0) { | ||
2572 | FOUND = 1; | 2809 | FOUND = 1; |
2573 | break; | 2810 | break; |
2574 | } | 2811 | } |
@@ -3053,8 +3290,7 @@ static void do_cciss_request(struct request_queue *q) | |||
3053 | /* The first 2 bits are reserved for controller error reporting. */ | 3290 | /* The first 2 bits are reserved for controller error reporting. */ |
3054 | c->Header.Tag.lower = (c->cmdindex << 3); | 3291 | c->Header.Tag.lower = (c->cmdindex << 3); |
3055 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ | 3292 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ |
3056 | c->Header.LUN.LogDev.VolId = drv->LunID; | 3293 | memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); |
3057 | c->Header.LUN.LogDev.Mode = 1; | ||
3058 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; | 3294 | c->Request.CDBLen = 10; // 12 byte commands not in FW yet; |
3059 | c->Request.Type.Type = TYPE_CMD; // It is a command. | 3295 | c->Request.Type.Type = TYPE_CMD; // It is a command. |
3060 | c->Request.Type.Attribute = ATTR_SIMPLE; | 3296 | c->Request.Type.Attribute = ATTR_SIMPLE; |
@@ -3232,20 +3468,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) | |||
3232 | return IRQ_HANDLED; | 3468 | return IRQ_HANDLED; |
3233 | } | 3469 | } |
3234 | 3470 | ||
3471 | /** | ||
3472 | * add_to_scan_list() - add controller to rescan queue | ||
3473 | * @h: Pointer to the controller. | ||
3474 | * | ||
3475 | * Adds the controller to the rescan queue if not already on the queue. | ||
3476 | * | ||
3477 | * returns 1 if added to the queue, 0 if skipped (could be on the | ||
3478 | * queue already, or the controller could be initializing or shutting | ||
3479 | * down). | ||
3480 | **/ | ||
3481 | static int add_to_scan_list(struct ctlr_info *h) | ||
3482 | { | ||
3483 | struct ctlr_info *test_h; | ||
3484 | int found = 0; | ||
3485 | int ret = 0; | ||
3486 | |||
3487 | if (h->busy_initializing) | ||
3488 | return 0; | ||
3489 | |||
3490 | if (!mutex_trylock(&h->busy_shutting_down)) | ||
3491 | return 0; | ||
3492 | |||
3493 | mutex_lock(&scan_mutex); | ||
3494 | list_for_each_entry(test_h, &scan_q, scan_list) { | ||
3495 | if (test_h == h) { | ||
3496 | found = 1; | ||
3497 | break; | ||
3498 | } | ||
3499 | } | ||
3500 | if (!found && !h->busy_scanning) { | ||
3501 | INIT_COMPLETION(h->scan_wait); | ||
3502 | list_add_tail(&h->scan_list, &scan_q); | ||
3503 | ret = 1; | ||
3504 | } | ||
3505 | mutex_unlock(&scan_mutex); | ||
3506 | mutex_unlock(&h->busy_shutting_down); | ||
3507 | |||
3508 | return ret; | ||
3509 | } | ||
3510 | |||
3511 | /** | ||
3512 | * remove_from_scan_list() - remove controller from rescan queue | ||
3513 | * @h: Pointer to the controller. | ||
3514 | * | ||
3515 | * Removes the controller from the rescan queue if present. Blocks if | ||
3516 | * the controller is currently conducting a rescan. | ||
3517 | **/ | ||
3518 | static void remove_from_scan_list(struct ctlr_info *h) | ||
3519 | { | ||
3520 | struct ctlr_info *test_h, *tmp_h; | ||
3521 | int scanning = 0; | ||
3522 | |||
3523 | mutex_lock(&scan_mutex); | ||
3524 | list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) { | ||
3525 | if (test_h == h) { | ||
3526 | list_del(&h->scan_list); | ||
3527 | complete_all(&h->scan_wait); | ||
3528 | mutex_unlock(&scan_mutex); | ||
3529 | return; | ||
3530 | } | ||
3531 | } | ||
3532 | if (&h->busy_scanning) | ||
3533 | scanning = 0; | ||
3534 | mutex_unlock(&scan_mutex); | ||
3535 | |||
3536 | if (scanning) | ||
3537 | wait_for_completion(&h->scan_wait); | ||
3538 | } | ||
3539 | |||
3540 | /** | ||
3541 | * scan_thread() - kernel thread used to rescan controllers | ||
3542 | * @data: Ignored. | ||
3543 | * | ||
3544 | * A kernel thread used scan for drive topology changes on | ||
3545 | * controllers. The thread processes only one controller at a time | ||
3546 | * using a queue. Controllers are added to the queue using | ||
3547 | * add_to_scan_list() and removed from the queue either after done | ||
3548 | * processing or using remove_from_scan_list(). | ||
3549 | * | ||
3550 | * returns 0. | ||
3551 | **/ | ||
3235 | static int scan_thread(void *data) | 3552 | static int scan_thread(void *data) |
3236 | { | 3553 | { |
3237 | ctlr_info_t *h = data; | 3554 | struct ctlr_info *h; |
3238 | int rc; | ||
3239 | DECLARE_COMPLETION_ONSTACK(wait); | ||
3240 | h->rescan_wait = &wait; | ||
3241 | 3555 | ||
3242 | for (;;) { | 3556 | while (1) { |
3243 | rc = wait_for_completion_interruptible(&wait); | 3557 | set_current_state(TASK_INTERRUPTIBLE); |
3558 | schedule(); | ||
3244 | if (kthread_should_stop()) | 3559 | if (kthread_should_stop()) |
3245 | break; | 3560 | break; |
3246 | if (!rc) | 3561 | |
3247 | rebuild_lun_table(h, 0); | 3562 | while (1) { |
3563 | mutex_lock(&scan_mutex); | ||
3564 | if (list_empty(&scan_q)) { | ||
3565 | mutex_unlock(&scan_mutex); | ||
3566 | break; | ||
3567 | } | ||
3568 | |||
3569 | h = list_entry(scan_q.next, | ||
3570 | struct ctlr_info, | ||
3571 | scan_list); | ||
3572 | list_del(&h->scan_list); | ||
3573 | h->busy_scanning = 1; | ||
3574 | mutex_unlock(&scan_mutex); | ||
3575 | |||
3576 | if (h) { | ||
3577 | rebuild_lun_table(h, 0, 0); | ||
3578 | complete_all(&h->scan_wait); | ||
3579 | mutex_lock(&scan_mutex); | ||
3580 | h->busy_scanning = 0; | ||
3581 | mutex_unlock(&scan_mutex); | ||
3582 | } | ||
3583 | } | ||
3248 | } | 3584 | } |
3585 | |||
3249 | return 0; | 3586 | return 0; |
3250 | } | 3587 | } |
3251 | 3588 | ||
@@ -3268,8 +3605,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) | |||
3268 | case REPORT_LUNS_CHANGED: | 3605 | case REPORT_LUNS_CHANGED: |
3269 | printk(KERN_WARNING "cciss%d: report LUN data " | 3606 | printk(KERN_WARNING "cciss%d: report LUN data " |
3270 | "changed\n", h->ctlr); | 3607 | "changed\n", h->ctlr); |
3271 | if (h->rescan_wait) | 3608 | add_to_scan_list(h); |
3272 | complete(h->rescan_wait); | 3609 | wake_up_process(cciss_scan_thread); |
3273 | return 1; | 3610 | return 1; |
3274 | break; | 3611 | break; |
3275 | case POWER_OR_RESET: | 3612 | case POWER_OR_RESET: |
@@ -3422,7 +3759,27 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3422 | __u64 cfg_offset; | 3759 | __u64 cfg_offset; |
3423 | __u32 cfg_base_addr; | 3760 | __u32 cfg_base_addr; |
3424 | __u64 cfg_base_addr_index; | 3761 | __u64 cfg_base_addr_index; |
3425 | int i, err; | 3762 | int i, prod_index, err; |
3763 | |||
3764 | subsystem_vendor_id = pdev->subsystem_vendor; | ||
3765 | subsystem_device_id = pdev->subsystem_device; | ||
3766 | board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | | ||
3767 | subsystem_vendor_id); | ||
3768 | |||
3769 | for (i = 0; i < ARRAY_SIZE(products); i++) { | ||
3770 | /* Stand aside for hpsa driver on request */ | ||
3771 | if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY) | ||
3772 | return -ENODEV; | ||
3773 | if (board_id == products[i].board_id) | ||
3774 | break; | ||
3775 | } | ||
3776 | prod_index = i; | ||
3777 | if (prod_index == ARRAY_SIZE(products)) { | ||
3778 | dev_warn(&pdev->dev, | ||
3779 | "unrecognized board ID: 0x%08lx, ignoring.\n", | ||
3780 | (unsigned long) board_id); | ||
3781 | return -ENODEV; | ||
3782 | } | ||
3426 | 3783 | ||
3427 | /* check to see if controller has been disabled */ | 3784 | /* check to see if controller has been disabled */ |
3428 | /* BEFORE trying to enable it */ | 3785 | /* BEFORE trying to enable it */ |
@@ -3446,11 +3803,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3446 | return err; | 3803 | return err; |
3447 | } | 3804 | } |
3448 | 3805 | ||
3449 | subsystem_vendor_id = pdev->subsystem_vendor; | ||
3450 | subsystem_device_id = pdev->subsystem_device; | ||
3451 | board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | | ||
3452 | subsystem_vendor_id); | ||
3453 | |||
3454 | #ifdef CCISS_DEBUG | 3806 | #ifdef CCISS_DEBUG |
3455 | printk("command = %x\n", command); | 3807 | printk("command = %x\n", command); |
3456 | printk("irq = %x\n", pdev->irq); | 3808 | printk("irq = %x\n", pdev->irq); |
@@ -3489,7 +3841,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3489 | if (scratchpad == CCISS_FIRMWARE_READY) | 3841 | if (scratchpad == CCISS_FIRMWARE_READY) |
3490 | break; | 3842 | break; |
3491 | set_current_state(TASK_INTERRUPTIBLE); | 3843 | set_current_state(TASK_INTERRUPTIBLE); |
3492 | schedule_timeout(HZ / 10); /* wait 100ms */ | 3844 | schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */ |
3493 | } | 3845 | } |
3494 | if (scratchpad != CCISS_FIRMWARE_READY) { | 3846 | if (scratchpad != CCISS_FIRMWARE_READY) { |
3495 | printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); | 3847 | printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); |
@@ -3536,14 +3888,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3536 | * leave a little room for ioctl calls. | 3888 | * leave a little room for ioctl calls. |
3537 | */ | 3889 | */ |
3538 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); | 3890 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); |
3539 | for (i = 0; i < ARRAY_SIZE(products); i++) { | 3891 | c->product_name = products[prod_index].product_name; |
3540 | if (board_id == products[i].board_id) { | 3892 | c->access = *(products[prod_index].access); |
3541 | c->product_name = products[i].product_name; | 3893 | c->nr_cmds = c->max_commands - 4; |
3542 | c->access = *(products[i].access); | ||
3543 | c->nr_cmds = c->max_commands - 4; | ||
3544 | break; | ||
3545 | } | ||
3546 | } | ||
3547 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || | 3894 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || |
3548 | (readb(&c->cfgtable->Signature[1]) != 'I') || | 3895 | (readb(&c->cfgtable->Signature[1]) != 'I') || |
3549 | (readb(&c->cfgtable->Signature[2]) != 'S') || | 3896 | (readb(&c->cfgtable->Signature[2]) != 'S') || |
@@ -3552,27 +3899,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3552 | err = -ENODEV; | 3899 | err = -ENODEV; |
3553 | goto err_out_free_res; | 3900 | goto err_out_free_res; |
3554 | } | 3901 | } |
3555 | /* We didn't find the controller in our list. We know the | ||
3556 | * signature is valid. If it's an HP device let's try to | ||
3557 | * bind to the device and fire it up. Otherwise we bail. | ||
3558 | */ | ||
3559 | if (i == ARRAY_SIZE(products)) { | ||
3560 | if (subsystem_vendor_id == PCI_VENDOR_ID_HP) { | ||
3561 | c->product_name = products[i-1].product_name; | ||
3562 | c->access = *(products[i-1].access); | ||
3563 | c->nr_cmds = c->max_commands - 4; | ||
3564 | printk(KERN_WARNING "cciss: This is an unknown " | ||
3565 | "Smart Array controller.\n" | ||
3566 | "cciss: Please update to the latest driver " | ||
3567 | "available from www.hp.com.\n"); | ||
3568 | } else { | ||
3569 | printk(KERN_WARNING "cciss: Sorry, I don't know how" | ||
3570 | " to access the Smart Array controller %08lx\n" | ||
3571 | , (unsigned long)board_id); | ||
3572 | err = -ENODEV; | ||
3573 | goto err_out_free_res; | ||
3574 | } | ||
3575 | } | ||
3576 | #ifdef CONFIG_X86 | 3902 | #ifdef CONFIG_X86 |
3577 | { | 3903 | { |
3578 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | 3904 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ |
@@ -3615,7 +3941,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3615 | break; | 3941 | break; |
3616 | /* delay and try again */ | 3942 | /* delay and try again */ |
3617 | set_current_state(TASK_INTERRUPTIBLE); | 3943 | set_current_state(TASK_INTERRUPTIBLE); |
3618 | schedule_timeout(10); | 3944 | schedule_timeout(msecs_to_jiffies(1)); |
3619 | } | 3945 | } |
3620 | 3946 | ||
3621 | #ifdef CCISS_DEBUG | 3947 | #ifdef CCISS_DEBUG |
@@ -3669,15 +3995,16 @@ Enomem: | |||
3669 | return -1; | 3995 | return -1; |
3670 | } | 3996 | } |
3671 | 3997 | ||
3672 | static void free_hba(int i) | 3998 | static void free_hba(int n) |
3673 | { | 3999 | { |
3674 | ctlr_info_t *p = hba[i]; | 4000 | ctlr_info_t *h = hba[n]; |
3675 | int n; | 4001 | int i; |
3676 | 4002 | ||
3677 | hba[i] = NULL; | 4003 | hba[n] = NULL; |
3678 | for (n = 0; n < CISS_MAX_LUN; n++) | 4004 | for (i = 0; i < h->highest_lun + 1; i++) |
3679 | put_disk(p->gendisk[n]); | 4005 | if (h->gendisk[i] != NULL) |
3680 | kfree(p); | 4006 | put_disk(h->gendisk[i]); |
4007 | kfree(h); | ||
3681 | } | 4008 | } |
3682 | 4009 | ||
3683 | /* Send a message CDB to the firmware. */ | 4010 | /* Send a message CDB to the firmware. */ |
@@ -3918,14 +4245,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3918 | hba[i]->busy_initializing = 1; | 4245 | hba[i]->busy_initializing = 1; |
3919 | INIT_HLIST_HEAD(&hba[i]->cmpQ); | 4246 | INIT_HLIST_HEAD(&hba[i]->cmpQ); |
3920 | INIT_HLIST_HEAD(&hba[i]->reqQ); | 4247 | INIT_HLIST_HEAD(&hba[i]->reqQ); |
4248 | mutex_init(&hba[i]->busy_shutting_down); | ||
3921 | 4249 | ||
3922 | if (cciss_pci_init(hba[i], pdev) != 0) | 4250 | if (cciss_pci_init(hba[i], pdev) != 0) |
3923 | goto clean0; | 4251 | goto clean_no_release_regions; |
3924 | 4252 | ||
3925 | sprintf(hba[i]->devname, "cciss%d", i); | 4253 | sprintf(hba[i]->devname, "cciss%d", i); |
3926 | hba[i]->ctlr = i; | 4254 | hba[i]->ctlr = i; |
3927 | hba[i]->pdev = pdev; | 4255 | hba[i]->pdev = pdev; |
3928 | 4256 | ||
4257 | init_completion(&hba[i]->scan_wait); | ||
4258 | |||
3929 | if (cciss_create_hba_sysfs_entry(hba[i])) | 4259 | if (cciss_create_hba_sysfs_entry(hba[i])) |
3930 | goto clean0; | 4260 | goto clean0; |
3931 | 4261 | ||
@@ -4001,8 +4331,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4001 | hba[i]->num_luns = 0; | 4331 | hba[i]->num_luns = 0; |
4002 | hba[i]->highest_lun = -1; | 4332 | hba[i]->highest_lun = -1; |
4003 | for (j = 0; j < CISS_MAX_LUN; j++) { | 4333 | for (j = 0; j < CISS_MAX_LUN; j++) { |
4004 | hba[i]->drv[j].raid_level = -1; | 4334 | hba[i]->drv[j] = NULL; |
4005 | hba[i]->drv[j].queue = NULL; | ||
4006 | hba[i]->gendisk[j] = NULL; | 4335 | hba[i]->gendisk[j] = NULL; |
4007 | } | 4336 | } |
4008 | 4337 | ||
@@ -4035,14 +4364,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4035 | 4364 | ||
4036 | hba[i]->cciss_max_sectors = 2048; | 4365 | hba[i]->cciss_max_sectors = 2048; |
4037 | 4366 | ||
4367 | rebuild_lun_table(hba[i], 1, 0); | ||
4038 | hba[i]->busy_initializing = 0; | 4368 | hba[i]->busy_initializing = 0; |
4039 | |||
4040 | rebuild_lun_table(hba[i], 1); | ||
4041 | hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i], | ||
4042 | "cciss_scan%02d", i); | ||
4043 | if (IS_ERR(hba[i]->cciss_scan_thread)) | ||
4044 | return PTR_ERR(hba[i]->cciss_scan_thread); | ||
4045 | |||
4046 | return 1; | 4369 | return 1; |
4047 | 4370 | ||
4048 | clean4: | 4371 | clean4: |
@@ -4062,18 +4385,14 @@ clean2: | |||
4062 | clean1: | 4385 | clean1: |
4063 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4386 | cciss_destroy_hba_sysfs_entry(hba[i]); |
4064 | clean0: | 4387 | clean0: |
4388 | pci_release_regions(pdev); | ||
4389 | clean_no_release_regions: | ||
4065 | hba[i]->busy_initializing = 0; | 4390 | hba[i]->busy_initializing = 0; |
4066 | /* cleanup any queues that may have been initialized */ | 4391 | |
4067 | for (j=0; j <= hba[i]->highest_lun; j++){ | ||
4068 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
4069 | if (drv->queue) | ||
4070 | blk_cleanup_queue(drv->queue); | ||
4071 | } | ||
4072 | /* | 4392 | /* |
4073 | * Deliberately omit pci_disable_device(): it does something nasty to | 4393 | * Deliberately omit pci_disable_device(): it does something nasty to |
4074 | * Smart Array controllers that pci_enable_device does not undo | 4394 | * Smart Array controllers that pci_enable_device does not undo |
4075 | */ | 4395 | */ |
4076 | pci_release_regions(pdev); | ||
4077 | pci_set_drvdata(pdev, NULL); | 4396 | pci_set_drvdata(pdev, NULL); |
4078 | free_hba(i); | 4397 | free_hba(i); |
4079 | return -1; | 4398 | return -1; |
@@ -4125,8 +4444,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
4125 | return; | 4444 | return; |
4126 | } | 4445 | } |
4127 | 4446 | ||
4128 | kthread_stop(hba[i]->cciss_scan_thread); | 4447 | mutex_lock(&hba[i]->busy_shutting_down); |
4129 | 4448 | ||
4449 | remove_from_scan_list(hba[i]); | ||
4130 | remove_proc_entry(hba[i]->devname, proc_cciss); | 4450 | remove_proc_entry(hba[i]->devname, proc_cciss); |
4131 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 4451 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
4132 | 4452 | ||
@@ -4136,8 +4456,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
4136 | if (disk) { | 4456 | if (disk) { |
4137 | struct request_queue *q = disk->queue; | 4457 | struct request_queue *q = disk->queue; |
4138 | 4458 | ||
4139 | if (disk->flags & GENHD_FL_UP) | 4459 | if (disk->flags & GENHD_FL_UP) { |
4460 | cciss_destroy_ld_sysfs_entry(hba[i], j, 1); | ||
4140 | del_gendisk(disk); | 4461 | del_gendisk(disk); |
4462 | } | ||
4141 | if (q) | 4463 | if (q) |
4142 | blk_cleanup_queue(q); | 4464 | blk_cleanup_queue(q); |
4143 | } | 4465 | } |
@@ -4170,6 +4492,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
4170 | pci_release_regions(pdev); | 4492 | pci_release_regions(pdev); |
4171 | pci_set_drvdata(pdev, NULL); | 4493 | pci_set_drvdata(pdev, NULL); |
4172 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4494 | cciss_destroy_hba_sysfs_entry(hba[i]); |
4495 | mutex_unlock(&hba[i]->busy_shutting_down); | ||
4173 | free_hba(i); | 4496 | free_hba(i); |
4174 | } | 4497 | } |
4175 | 4498 | ||
@@ -4202,15 +4525,25 @@ static int __init cciss_init(void) | |||
4202 | if (err) | 4525 | if (err) |
4203 | return err; | 4526 | return err; |
4204 | 4527 | ||
4528 | /* Start the scan thread */ | ||
4529 | cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan"); | ||
4530 | if (IS_ERR(cciss_scan_thread)) { | ||
4531 | err = PTR_ERR(cciss_scan_thread); | ||
4532 | goto err_bus_unregister; | ||
4533 | } | ||
4534 | |||
4205 | /* Register for our PCI devices */ | 4535 | /* Register for our PCI devices */ |
4206 | err = pci_register_driver(&cciss_pci_driver); | 4536 | err = pci_register_driver(&cciss_pci_driver); |
4207 | if (err) | 4537 | if (err) |
4208 | goto err_bus_register; | 4538 | goto err_thread_stop; |
4209 | 4539 | ||
4210 | return 0; | 4540 | return err; |
4211 | 4541 | ||
4212 | err_bus_register: | 4542 | err_thread_stop: |
4543 | kthread_stop(cciss_scan_thread); | ||
4544 | err_bus_unregister: | ||
4213 | bus_unregister(&cciss_bus_type); | 4545 | bus_unregister(&cciss_bus_type); |
4546 | |||
4214 | return err; | 4547 | return err; |
4215 | } | 4548 | } |
4216 | 4549 | ||
@@ -4227,6 +4560,7 @@ static void __exit cciss_cleanup(void) | |||
4227 | cciss_remove_one(hba[i]->pdev); | 4560 | cciss_remove_one(hba[i]->pdev); |
4228 | } | 4561 | } |
4229 | } | 4562 | } |
4563 | kthread_stop(cciss_scan_thread); | ||
4230 | remove_proc_entry("driver/cciss", NULL); | 4564 | remove_proc_entry("driver/cciss", NULL); |
4231 | bus_unregister(&cciss_bus_type); | 4565 | bus_unregister(&cciss_bus_type); |
4232 | } | 4566 | } |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 06a5db25b298..31524cf42c77 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define CCISS_H | 2 | #define CCISS_H |
3 | 3 | ||
4 | #include <linux/genhd.h> | 4 | #include <linux/genhd.h> |
5 | #include <linux/mutex.h> | ||
5 | 6 | ||
6 | #include "cciss_cmd.h" | 7 | #include "cciss_cmd.h" |
7 | 8 | ||
@@ -29,7 +30,7 @@ struct access_method { | |||
29 | }; | 30 | }; |
30 | typedef struct _drive_info_struct | 31 | typedef struct _drive_info_struct |
31 | { | 32 | { |
32 | __u32 LunID; | 33 | unsigned char LunID[8]; |
33 | int usage_count; | 34 | int usage_count; |
34 | struct request_queue *queue; | 35 | struct request_queue *queue; |
35 | sector_t nr_blocks; | 36 | sector_t nr_blocks; |
@@ -51,6 +52,7 @@ typedef struct _drive_info_struct | |||
51 | char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ | 52 | char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ |
52 | char model[MODEL_LEN + 1]; /* SCSI model string */ | 53 | char model[MODEL_LEN + 1]; /* SCSI model string */ |
53 | char rev[REV_LEN + 1]; /* SCSI revision string */ | 54 | char rev[REV_LEN + 1]; /* SCSI revision string */ |
55 | char device_initialized; /* indicates whether dev is initialized */ | ||
54 | } drive_info_struct; | 56 | } drive_info_struct; |
55 | 57 | ||
56 | struct ctlr_info | 58 | struct ctlr_info |
@@ -86,7 +88,7 @@ struct ctlr_info | |||
86 | BYTE cciss_read_capacity; | 88 | BYTE cciss_read_capacity; |
87 | 89 | ||
88 | // information about each logical volume | 90 | // information about each logical volume |
89 | drive_info_struct drv[CISS_MAX_LUN]; | 91 | drive_info_struct *drv[CISS_MAX_LUN]; |
90 | 92 | ||
91 | struct access_method access; | 93 | struct access_method access; |
92 | 94 | ||
@@ -108,6 +110,8 @@ struct ctlr_info | |||
108 | int nr_frees; | 110 | int nr_frees; |
109 | int busy_configuring; | 111 | int busy_configuring; |
110 | int busy_initializing; | 112 | int busy_initializing; |
113 | int busy_scanning; | ||
114 | struct mutex busy_shutting_down; | ||
111 | 115 | ||
112 | /* This element holds the zero based queue number of the last | 116 | /* This element holds the zero based queue number of the last |
113 | * queue to be started. It is used for fairness. | 117 | * queue to be started. It is used for fairness. |
@@ -122,8 +126,8 @@ struct ctlr_info | |||
122 | /* and saved for later processing */ | 126 | /* and saved for later processing */ |
123 | #endif | 127 | #endif |
124 | unsigned char alive; | 128 | unsigned char alive; |
125 | struct completion *rescan_wait; | 129 | struct list_head scan_list; |
126 | struct task_struct *cciss_scan_thread; | 130 | struct completion scan_wait; |
127 | struct device dev; | 131 | struct device dev; |
128 | }; | 132 | }; |
129 | 133 | ||
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index b82d438e2607..6422651ec364 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/blkpg.h> | 32 | #include <linux/blkpg.h> |
33 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
35 | #include <linux/seq_file.h> | ||
35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
36 | #include <linux/hdreg.h> | 37 | #include <linux/hdreg.h> |
37 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
@@ -177,7 +178,6 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev); | |||
177 | 178 | ||
178 | #ifdef CONFIG_PROC_FS | 179 | #ifdef CONFIG_PROC_FS |
179 | static void ida_procinit(int i); | 180 | static void ida_procinit(int i); |
180 | static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data); | ||
181 | #else | 181 | #else |
182 | static void ida_procinit(int i) {} | 182 | static void ida_procinit(int i) {} |
183 | #endif | 183 | #endif |
@@ -206,6 +206,7 @@ static const struct block_device_operations ida_fops = { | |||
206 | #ifdef CONFIG_PROC_FS | 206 | #ifdef CONFIG_PROC_FS |
207 | 207 | ||
208 | static struct proc_dir_entry *proc_array; | 208 | static struct proc_dir_entry *proc_array; |
209 | static const struct file_operations ida_proc_fops; | ||
209 | 210 | ||
210 | /* | 211 | /* |
211 | * Get us a file in /proc/array that says something about each controller. | 212 | * Get us a file in /proc/array that says something about each controller. |
@@ -218,19 +219,16 @@ static void __init ida_procinit(int i) | |||
218 | if (!proc_array) return; | 219 | if (!proc_array) return; |
219 | } | 220 | } |
220 | 221 | ||
221 | create_proc_read_entry(hba[i]->devname, 0, proc_array, | 222 | proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]); |
222 | ida_proc_get_info, hba[i]); | ||
223 | } | 223 | } |
224 | 224 | ||
225 | /* | 225 | /* |
226 | * Report information about this controller. | 226 | * Report information about this controller. |
227 | */ | 227 | */ |
228 | static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) | 228 | static int ida_proc_show(struct seq_file *m, void *v) |
229 | { | 229 | { |
230 | off_t pos = 0; | 230 | int i, ctlr; |
231 | off_t len = 0; | 231 | ctlr_info_t *h = (ctlr_info_t*)m->private; |
232 | int size, i, ctlr; | ||
233 | ctlr_info_t *h = (ctlr_info_t*)data; | ||
234 | drv_info_t *drv; | 232 | drv_info_t *drv; |
235 | #ifdef CPQ_PROC_PRINT_QUEUES | 233 | #ifdef CPQ_PROC_PRINT_QUEUES |
236 | cmdlist_t *c; | 234 | cmdlist_t *c; |
@@ -238,7 +236,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt | |||
238 | #endif | 236 | #endif |
239 | 237 | ||
240 | ctlr = h->ctlr; | 238 | ctlr = h->ctlr; |
241 | size = sprintf(buffer, "%s: Compaq %s Controller\n" | 239 | seq_printf(m, "%s: Compaq %s Controller\n" |
242 | " Board ID: 0x%08lx\n" | 240 | " Board ID: 0x%08lx\n" |
243 | " Firmware Revision: %c%c%c%c\n" | 241 | " Firmware Revision: %c%c%c%c\n" |
244 | " Controller Sig: 0x%08lx\n" | 242 | " Controller Sig: 0x%08lx\n" |
@@ -258,55 +256,54 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt | |||
258 | h->log_drives, h->phys_drives, | 256 | h->log_drives, h->phys_drives, |
259 | h->Qdepth, h->maxQsinceinit); | 257 | h->Qdepth, h->maxQsinceinit); |
260 | 258 | ||
261 | pos += size; len += size; | 259 | seq_puts(m, "Logical Drive Info:\n"); |
262 | |||
263 | size = sprintf(buffer+len, "Logical Drive Info:\n"); | ||
264 | pos += size; len += size; | ||
265 | 260 | ||
266 | for(i=0; i<h->log_drives; i++) { | 261 | for(i=0; i<h->log_drives; i++) { |
267 | drv = &h->drv[i]; | 262 | drv = &h->drv[i]; |
268 | size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n", | 263 | seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n", |
269 | ctlr, i, drv->blk_size, drv->nr_blks); | 264 | ctlr, i, drv->blk_size, drv->nr_blks); |
270 | pos += size; len += size; | ||
271 | } | 265 | } |
272 | 266 | ||
273 | #ifdef CPQ_PROC_PRINT_QUEUES | 267 | #ifdef CPQ_PROC_PRINT_QUEUES |
274 | spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); | 268 | spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); |
275 | size = sprintf(buffer+len, "\nCurrent Queues:\n"); | 269 | seq_puts(m, "\nCurrent Queues:\n"); |
276 | pos += size; len += size; | ||
277 | 270 | ||
278 | c = h->reqQ; | 271 | c = h->reqQ; |
279 | size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size; | 272 | seq_printf(m, "reqQ = %p", c); |
280 | if (c) c=c->next; | 273 | if (c) c=c->next; |
281 | while(c && c != h->reqQ) { | 274 | while(c && c != h->reqQ) { |
282 | size = sprintf(buffer+len, "->%p", c); | 275 | seq_printf(m, "->%p", c); |
283 | pos += size; len += size; | ||
284 | c=c->next; | 276 | c=c->next; |
285 | } | 277 | } |
286 | 278 | ||
287 | c = h->cmpQ; | 279 | c = h->cmpQ; |
288 | size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size; | 280 | seq_printf(m, "\ncmpQ = %p", c); |
289 | if (c) c=c->next; | 281 | if (c) c=c->next; |
290 | while(c && c != h->cmpQ) { | 282 | while(c && c != h->cmpQ) { |
291 | size = sprintf(buffer+len, "->%p", c); | 283 | seq_printf(m, "->%p", c); |
292 | pos += size; len += size; | ||
293 | c=c->next; | 284 | c=c->next; |
294 | } | 285 | } |
295 | 286 | ||
296 | size = sprintf(buffer+len, "\n"); pos += size; len += size; | 287 | seq_putc(m, '\n'); |
297 | spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); | 288 | spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); |
298 | #endif | 289 | #endif |
299 | size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n", | 290 | seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n", |
300 | h->nr_allocs, h->nr_frees); | 291 | h->nr_allocs, h->nr_frees); |
301 | pos += size; len += size; | 292 | return 0; |
302 | 293 | } | |
303 | *eof = 1; | 294 | |
304 | *start = buffer+offset; | 295 | static int ida_proc_open(struct inode *inode, struct file *file) |
305 | len -= offset; | 296 | { |
306 | if (len>length) | 297 | return single_open(file, ida_proc_show, PDE(inode)->data); |
307 | len = length; | ||
308 | return len; | ||
309 | } | 298 | } |
299 | |||
300 | static const struct file_operations ida_proc_fops = { | ||
301 | .owner = THIS_MODULE, | ||
302 | .open = ida_proc_open, | ||
303 | .read = seq_read, | ||
304 | .llseek = seq_lseek, | ||
305 | .release = single_release, | ||
306 | }; | ||
310 | #endif /* CONFIG_PROC_FS */ | 307 | #endif /* CONFIG_PROC_FS */ |
311 | 308 | ||
312 | module_param_array(eisa, int, NULL, 0); | 309 | module_param_array(eisa, int, NULL, 0); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index edda9ea7c626..bd112c8c7bcd 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -949,7 +949,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
949 | lo->lo_state = Lo_unbound; | 949 | lo->lo_state = Lo_unbound; |
950 | /* This is safe: open() is still holding a reference. */ | 950 | /* This is safe: open() is still holding a reference. */ |
951 | module_put(THIS_MODULE); | 951 | module_put(THIS_MODULE); |
952 | if (max_part > 0) | 952 | if (max_part > 0 && bdev) |
953 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 953 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
954 | mutex_unlock(&lo->lo_ctl_mutex); | 954 | mutex_unlock(&lo->lo_ctl_mutex); |
955 | /* | 955 | /* |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 43f19389647a..51042f0ba7e1 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <linux/blkdev.h> | 3 | #include <linux/blkdev.h> |
4 | #include <linux/hdreg.h> | 4 | #include <linux/hdreg.h> |
5 | #include <linux/virtio.h> | 5 | #include <linux/virtio.h> |
6 | #include <linux/virtio_ids.h> | ||
7 | #include <linux/virtio_blk.h> | 6 | #include <linux/virtio_blk.h> |
8 | #include <linux/scatterlist.h> | 7 | #include <linux/scatterlist.h> |
9 | 8 | ||
@@ -183,34 +182,6 @@ static void do_virtblk_request(struct request_queue *q) | |||
183 | vblk->vq->vq_ops->kick(vblk->vq); | 182 | vblk->vq->vq_ops->kick(vblk->vq); |
184 | } | 183 | } |
185 | 184 | ||
186 | /* return ATA identify data | ||
187 | */ | ||
188 | static int virtblk_identify(struct gendisk *disk, void *argp) | ||
189 | { | ||
190 | struct virtio_blk *vblk = disk->private_data; | ||
191 | void *opaque; | ||
192 | int err = -ENOMEM; | ||
193 | |||
194 | opaque = kmalloc(VIRTIO_BLK_ID_BYTES, GFP_KERNEL); | ||
195 | if (!opaque) | ||
196 | goto out; | ||
197 | |||
198 | err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY, | ||
199 | offsetof(struct virtio_blk_config, identify), opaque, | ||
200 | VIRTIO_BLK_ID_BYTES); | ||
201 | |||
202 | if (err) | ||
203 | goto out_kfree; | ||
204 | |||
205 | if (copy_to_user(argp, opaque, VIRTIO_BLK_ID_BYTES)) | ||
206 | err = -EFAULT; | ||
207 | |||
208 | out_kfree: | ||
209 | kfree(opaque); | ||
210 | out: | ||
211 | return err; | ||
212 | } | ||
213 | |||
214 | static void virtblk_prepare_flush(struct request_queue *q, struct request *req) | 185 | static void virtblk_prepare_flush(struct request_queue *q, struct request *req) |
215 | { | 186 | { |
216 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; | 187 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; |
@@ -222,10 +193,6 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
222 | { | 193 | { |
223 | struct gendisk *disk = bdev->bd_disk; | 194 | struct gendisk *disk = bdev->bd_disk; |
224 | struct virtio_blk *vblk = disk->private_data; | 195 | struct virtio_blk *vblk = disk->private_data; |
225 | void __user *argp = (void __user *)data; | ||
226 | |||
227 | if (cmd == HDIO_GET_IDENTITY) | ||
228 | return virtblk_identify(disk, argp); | ||
229 | 196 | ||
230 | /* | 197 | /* |
231 | * Only allow the generic SCSI ioctls if the host can support it. | 198 | * Only allow the generic SCSI ioctls if the host can support it. |
@@ -233,7 +200,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
233 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) | 200 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) |
234 | return -ENOTTY; | 201 | return -ENOTTY; |
235 | 202 | ||
236 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); | 203 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, |
204 | (void __user *)data); | ||
237 | } | 205 | } |
238 | 206 | ||
239 | /* We provide getgeo only to please some old bootloader/partitioning tools */ | 207 | /* We provide getgeo only to please some old bootloader/partitioning tools */ |
@@ -332,7 +300,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
332 | } | 300 | } |
333 | 301 | ||
334 | vblk->disk->queue->queuedata = vblk; | 302 | vblk->disk->queue->queuedata = vblk; |
335 | queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue); | ||
336 | 303 | ||
337 | if (index < 26) { | 304 | if (index < 26) { |
338 | sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); | 305 | sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); |
@@ -445,7 +412,7 @@ static struct virtio_device_id id_table[] = { | |||
445 | static unsigned int features[] = { | 412 | static unsigned int features[] = { |
446 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, | 413 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, |
447 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, | 414 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, |
448 | VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH | 415 | VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_FLUSH |
449 | }; | 416 | }; |
450 | 417 | ||
451 | /* | 418 | /* |