cciss.c 105.4 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
M
Mike Miller 已提交
2 3
 *    Disk Array driver for HP Smart Array controllers.
 *    (C) Copyright 2000, 2007 Hewlett-Packard Development Company, L.P.
L
Linus Torvalds 已提交
4 5 6
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
M
Mike Miller 已提交
7
 *    the Free Software Foundation; version 2 of the License.
L
Linus Torvalds 已提交
8 9 10
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
M
Mike Miller 已提交
11 12
 *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *    General Public License for more details.
L
Linus Torvalds 已提交
13 14 15
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
M
Mike Miller 已提交
16 17
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *    02111-1307, USA.
L
Linus Torvalds 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 *
 *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
 *
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/bio.h>
#include <linux/blkpg.h>
#include <linux/timer.h>
#include <linux/proc_fs.h>
36
#include <linux/seq_file.h>
37
#include <linux/init.h>
L
Linus Torvalds 已提交
38 39 40
#include <linux/hdreg.h>
#include <linux/spinlock.h>
#include <linux/compat.h>
41
#include <linux/blktrace_api.h>
L
Linus Torvalds 已提交
42 43 44
#include <asm/uaccess.h>
#include <asm/io.h>

45
#include <linux/dma-mapping.h>
L
Linus Torvalds 已提交
46 47 48
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/completion.h>
49
#include <scsi/scsi.h>
50 51 52
#include <scsi/sg.h>
#include <scsi/scsi_ioctl.h>
#include <linux/cdrom.h>
53
#include <linux/scatterlist.h>
L
Linus Torvalds 已提交
54 55

#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
M
Mike Miller 已提交
56 57
#define DRIVER_NAME "HP CISS Driver (v 3.6.20)"
#define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20)
L
Linus Torvalds 已提交
58 59 60

/* Embedded module documentation macros - see modules.h */
MODULE_AUTHOR("Hewlett-Packard Company");
M
Mike Miller 已提交
61
MODULE_DESCRIPTION("Driver for HP Smart Array Controllers");
L
Linus Torvalds 已提交
62
MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
M
Mike Miller 已提交
63 64 65
			" SA6i P600 P800 P400 P400i E200 E200i E500 P700m"
			" Smart Array G2 Series SAS/SATA Controllers");
MODULE_VERSION("3.6.20");
L
Linus Torvalds 已提交
66 67 68 69 70 71 72 73
MODULE_LICENSE("GPL");

#include "cciss_cmd.h"
#include "cciss.h"
#include <linux/cciss_ioctl.h>

/* define the PCI info for the cards we can control */
static const struct pci_device_id cciss_pci_device_id[] = {
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS,  0x0E11, 0x4070},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4080},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4082},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB, 0x0E11, 0x4083},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x4091},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409A},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409B},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409C},
	{PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC, 0x0E11, 0x409D},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSA,     0x103C, 0x3225},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3223},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3234},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3235},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3211},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3212},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3213},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3214},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSD,     0x103C, 0x3215},
92
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x3237},
93
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSC,     0x103C, 0x323D},
M
Mike Miller 已提交
94 95 96 97 98
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3241},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3243},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3245},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3247},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
99 100
	{PCI_VENDOR_ID_HP,     PCI_ANY_ID,	PCI_ANY_ID, PCI_ANY_ID,
		PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
L
Linus Torvalds 已提交
101 102
	{0,}
};
103

L
Linus Torvalds 已提交
104 105 106 107
MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);

/*  board_id = Subsystem Device ID & Vendor ID
 *  product = Marketing Name for the board
108
 *  access = Address of the struct of function pointers
109
 *  nr_cmds = Number of commands supported by controller
L
Linus Torvalds 已提交
110 111
 */
static struct board_type products[] = {
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
	{0x40700E11, "Smart Array 5300", &SA5_access, 512},
	{0x40800E11, "Smart Array 5i", &SA5B_access, 512},
	{0x40820E11, "Smart Array 532", &SA5B_access, 512},
	{0x40830E11, "Smart Array 5312", &SA5B_access, 512},
	{0x409A0E11, "Smart Array 641", &SA5_access, 512},
	{0x409B0E11, "Smart Array 642", &SA5_access, 512},
	{0x409C0E11, "Smart Array 6400", &SA5_access, 512},
	{0x409D0E11, "Smart Array 6400 EM", &SA5_access, 512},
	{0x40910E11, "Smart Array 6i", &SA5_access, 512},
	{0x3225103C, "Smart Array P600", &SA5_access, 512},
	{0x3223103C, "Smart Array P800", &SA5_access, 512},
	{0x3234103C, "Smart Array P400", &SA5_access, 512},
	{0x3235103C, "Smart Array P400i", &SA5_access, 512},
	{0x3211103C, "Smart Array E200i", &SA5_access, 120},
	{0x3212103C, "Smart Array E200", &SA5_access, 120},
	{0x3213103C, "Smart Array E200i", &SA5_access, 120},
	{0x3214103C, "Smart Array E200i", &SA5_access, 120},
	{0x3215103C, "Smart Array E200i", &SA5_access, 120},
130
	{0x3237103C, "Smart Array E500", &SA5_access, 512},
131
	{0x323D103C, "Smart Array P700m", &SA5_access, 512},
M
Mike Miller 已提交
132 133 134 135 136
	{0x3241103C, "Smart Array P212", &SA5_access, 384},
	{0x3243103C, "Smart Array P410", &SA5_access, 384},
	{0x3245103C, "Smart Array P410i", &SA5_access, 384},
	{0x3247103C, "Smart Array P411", &SA5_access, 384},
	{0x3249103C, "Smart Array P812", &SA5_access, 384},
137
	{0xFFFF103C, "Unknown Smart Array", &SA5_access, 120},
L
Linus Torvalds 已提交
138 139
};

140
/* How long to wait (in milliseconds) for board to go into simple mode */
141
#define MAX_CONFIG_WAIT 30000
L
Linus Torvalds 已提交
142 143 144 145 146 147 148 149 150 151 152 153
#define MAX_IOCTL_CONFIG_WAIT 1000

/*define how many times we will try a command because of bus resets */
#define MAX_CMD_RETRIES 3

#define MAX_CTLR	32

/* Originally cciss driver only supports 8 major numbers */
#define MAX_CTLR_ORIG 	8

static ctlr_info_t *hba[MAX_CTLR];

154
static void do_cciss_request(struct request_queue *q);
155
static irqreturn_t do_cciss_intr(int irq, void *dev_id);
L
Linus Torvalds 已提交
156 157
static int cciss_open(struct inode *inode, struct file *filep);
static int cciss_release(struct inode *inode, struct file *filep);
158 159
static int cciss_ioctl(struct inode *inode, struct file *filep,
		       unsigned int cmd, unsigned long arg);
160
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
L
Linus Torvalds 已提交
161 162

static int cciss_revalidate(struct gendisk *disk);
163
static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
164 165
static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
			   int clear_all);
L
Linus Torvalds 已提交
166

167 168 169 170 171 172 173
static void cciss_read_capacity(int ctlr, int logvol, int withirq,
			sector_t *total_size, unsigned int *block_size);
static void cciss_read_capacity_16(int ctlr, int logvol, int withirq,
			sector_t *total_size, unsigned int *block_size);
static void cciss_geometry_inquiry(int ctlr, int logvol,
			int withirq, sector_t total_size,
			unsigned int block_size, InquiryData_struct *inq_buff,
174
				   drive_info_struct *drv);
L
Linus Torvalds 已提交
175
static void cciss_getgeometry(int cntl_num);
176 177 178 179 180 181 182 183 184
static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *,
					   __u32);
static void start_io(ctlr_info_t *h);
static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size,
		   unsigned int use_unit_num, unsigned int log_unit,
		   __u8 page_code, unsigned char *scsi3addr, int cmd_type);
static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size,
			   unsigned int use_unit_num, unsigned int log_unit,
			   __u8 page_code, int cmd_type);
L
Linus Torvalds 已提交
185

186 187
static void fail_all_cmds(unsigned long ctlr);

L
Linus Torvalds 已提交
188 189 190
#ifdef CONFIG_PROC_FS
static void cciss_procinit(int i);
#else
191 192 193 194
static void cciss_procinit(int i)
{
}
#endif				/* CONFIG_PROC_FS */
L
Linus Torvalds 已提交
195 196 197 198 199

#ifdef CONFIG_COMPAT
static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
#endif

200 201 202 203 204 205
static struct block_device_operations cciss_fops = {
	.owner = THIS_MODULE,
	.open = cciss_open,
	.release = cciss_release,
	.ioctl = cciss_ioctl,
	.getgeo = cciss_getgeo,
L
Linus Torvalds 已提交
206
#ifdef CONFIG_COMPAT
207
	.compat_ioctl = cciss_compat_ioctl,
L
Linus Torvalds 已提交
208
#endif
209
	.revalidate_disk = cciss_revalidate,
L
Linus Torvalds 已提交
210 211 212 213 214 215 216
};

/*
 * Enqueuing and dequeuing functions for cmdlists.
 */
static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)
{
217 218 219 220 221 222 223 224 225
	if (*Qptr == NULL) {
		*Qptr = c;
		c->next = c->prev = c;
	} else {
		c->prev = (*Qptr)->prev;
		c->next = (*Qptr);
		(*Qptr)->prev->next = c;
		(*Qptr)->prev = c;
	}
L
Linus Torvalds 已提交
226 227
}

228 229
static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
					  CommandList_struct *c)
L
Linus Torvalds 已提交
230
{
231 232 233 234 235 236 237 238 239
	if (c && c->next != c) {
		if (*Qptr == c)
			*Qptr = c->next;
		c->prev->next = c->next;
		c->next->prev = c->prev;
	} else {
		*Qptr = NULL;
	}
	return c;
L
Linus Torvalds 已提交
240 241 242 243
}

#include "cciss_scsi.c"		/* For SCSI tape support */

R
Randy Dunlap 已提交
244 245
#define RAID_UNKNOWN 6

L
Linus Torvalds 已提交
246 247 248 249 250 251 252
#ifdef CONFIG_PROC_FS

/*
 * Report information about this controller.
 */
#define ENG_GIG 1000000000
#define ENG_GIG_FACTOR (ENG_GIG/512)
253
#define ENGAGE_SCSI	"engage scsi"
254 255 256
static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
	"UNKNOWN"
};
L
Linus Torvalds 已提交
257 258 259

static struct proc_dir_entry *proc_cciss;

260
static void cciss_seq_show_header(struct seq_file *seq)
L
Linus Torvalds 已提交
261
{
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
	ctlr_info_t *h = seq->private;

	seq_printf(seq, "%s: HP %s Controller\n"
		"Board ID: 0x%08lx\n"
		"Firmware Version: %c%c%c%c\n"
		"IRQ: %d\n"
		"Logical drives: %d\n"
		"Current Q depth: %d\n"
		"Current # commands on controller: %d\n"
		"Max Q depth since init: %d\n"
		"Max # commands on controller since init: %d\n"
		"Max SG entries since init: %d\n",
		h->devname,
		h->product_name,
		(unsigned long)h->board_id,
		h->firm_ver[0], h->firm_ver[1], h->firm_ver[2],
		h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT],
		h->num_luns,
		h->Qdepth, h->commands_outstanding,
		h->maxQsinceinit, h->max_outstanding, h->maxSG);

#ifdef CONFIG_CISS_SCSI_TAPE
	cciss_seq_tape_report(seq, h->ctlr);
#endif /* CONFIG_CISS_SCSI_TAPE */
}
L
Linus Torvalds 已提交
287

288 289 290 291 292
static void *cciss_seq_start(struct seq_file *seq, loff_t *pos)
{
	ctlr_info_t *h = seq->private;
	unsigned ctlr = h->ctlr;
	unsigned long flags;
L
Linus Torvalds 已提交
293 294 295 296 297 298 299

	/* prevent displaying bogus info during configuration
	 * or deconfiguration of a logical volume
	 */
	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	if (h->busy_configuring) {
		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
300
		return ERR_PTR(-EBUSY);
L
Linus Torvalds 已提交
301 302 303 304
	}
	h->busy_configuring = 1;
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
	if (*pos == 0)
		cciss_seq_show_header(seq);

	return pos;
}

static int cciss_seq_show(struct seq_file *seq, void *v)
{
	sector_t vol_sz, vol_sz_frac;
	ctlr_info_t *h = seq->private;
	unsigned ctlr = h->ctlr;
	loff_t *pos = v;
	drive_info_struct *drv = &h->drv[*pos];

	if (*pos > h->highest_lun)
		return 0;

	if (drv->heads == 0)
		return 0;

	vol_sz = drv->nr_blocks;
	vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR);
	vol_sz_frac *= 100;
	sector_div(vol_sz_frac, ENG_GIG_FACTOR);

	if (drv->raid_level > 5)
		drv->raid_level = RAID_UNKNOWN;
	seq_printf(seq, "cciss/c%dd%d:"
			"\t%4u.%02uGB\tRAID %s\n",
			ctlr, (int) *pos, (int)vol_sz, (int)vol_sz_frac,
			raid_label[drv->raid_level]);
	return 0;
}

static void *cciss_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	ctlr_info_t *h = seq->private;

	if (*pos > h->highest_lun)
		return NULL;
	*pos += 1;

	return pos;
}

static void cciss_seq_stop(struct seq_file *seq, void *v)
{
	ctlr_info_t *h = seq->private;

	/* Only reset h->busy_configuring if we succeeded in setting
	 * it during cciss_seq_start. */
	if (v == ERR_PTR(-EBUSY))
		return;
358

L
Linus Torvalds 已提交
359 360 361
	h->busy_configuring = 0;
}

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
static struct seq_operations cciss_seq_ops = {
	.start = cciss_seq_start,
	.show  = cciss_seq_show,
	.next  = cciss_seq_next,
	.stop  = cciss_seq_stop,
};

static int cciss_seq_open(struct inode *inode, struct file *file)
{
	int ret = seq_open(file, &cciss_seq_ops);
	struct seq_file *seq = file->private_data;

	if (!ret)
		seq->private = PDE(inode)->data;

	return ret;
}

static ssize_t
cciss_proc_write(struct file *file, const char __user *buf,
		 size_t length, loff_t *ppos)
L
Linus Torvalds 已提交
383
{
384 385 386 387 388
	int err;
	char *buffer;

#ifndef CONFIG_CISS_SCSI_TAPE
	return -EINVAL;
L
Linus Torvalds 已提交
389 390
#endif

391
	if (!buf || length > PAGE_SIZE - 1)
392
		return -EINVAL;
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408

	buffer = (char *)__get_free_page(GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	err = -EFAULT;
	if (copy_from_user(buffer, buf, length))
		goto out;
	buffer[length] = '\0';

#ifdef CONFIG_CISS_SCSI_TAPE
	if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) {
		struct seq_file *seq = file->private_data;
		ctlr_info_t *h = seq->private;
		int rc;

409 410
		rc = cciss_engage_scsi(h->ctlr);
		if (rc != 0)
411 412 413 414 415 416
			err = -rc;
		else
			err = length;
	} else
#endif /* CONFIG_CISS_SCSI_TAPE */
		err = -EINVAL;
417 418
	/* might be nice to have "disengage" too, but it's not
	   safely possible. (only 1 module use count, lock issues.) */
419 420 421 422

out:
	free_page((unsigned long)buffer);
	return err;
L
Linus Torvalds 已提交
423 424
}

425 426 427 428 429 430 431 432 433
static struct file_operations cciss_proc_fops = {
	.owner	 = THIS_MODULE,
	.open    = cciss_seq_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release,
	.write	 = cciss_proc_write,
};

L
Linus Torvalds 已提交
434 435 436 437
static void __devinit cciss_procinit(int i)
{
	struct proc_dir_entry *pde;

438
	if (proc_cciss == NULL)
A
Alexey Dobriyan 已提交
439
		proc_cciss = proc_mkdir("driver/cciss", NULL);
440 441
	if (!proc_cciss)
		return;
442
	pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP |
443
					S_IROTH, proc_cciss,
444
					&cciss_proc_fops, hba[i]);
L
Linus Torvalds 已提交
445
}
446
#endif				/* CONFIG_PROC_FS */
L
Linus Torvalds 已提交
447

448 449
/*
 * For operations that cannot sleep, a command block is allocated at init,
L
Linus Torvalds 已提交
450
 * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
451 452 453 454 455
 * which ones are free or in use.  For operations that can wait for kmalloc
 * to possible sleep, this routine can be called with get_from_pool set to 0.
 * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was.
 */
static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool)
L
Linus Torvalds 已提交
456 457
{
	CommandList_struct *c;
458
	int i;
L
Linus Torvalds 已提交
459 460 461
	u64bit temp64;
	dma_addr_t cmd_dma_handle, err_dma_handle;

462 463 464 465 466
	if (!get_from_pool) {
		c = (CommandList_struct *) pci_alloc_consistent(h->pdev,
			sizeof(CommandList_struct), &cmd_dma_handle);
		if (c == NULL)
			return NULL;
L
Linus Torvalds 已提交
467 468
		memset(c, 0, sizeof(CommandList_struct));

469 470
		c->cmdindex = -1;

471 472 473 474 475 476
		c->err_info = (ErrorInfo_struct *)
		    pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct),
			    &err_dma_handle);

		if (c->err_info == NULL) {
			pci_free_consistent(h->pdev,
L
Linus Torvalds 已提交
477 478 479 480
				sizeof(CommandList_struct), c, cmd_dma_handle);
			return NULL;
		}
		memset(c->err_info, 0, sizeof(ErrorInfo_struct));
481 482 483
	} else {		/* get it out of the controllers pool */

		do {
484 485
			i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
			if (i == h->nr_cmds)
486 487 488 489
				return NULL;
		} while (test_and_set_bit
			 (i & (BITS_PER_LONG - 1),
			  h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0);
L
Linus Torvalds 已提交
490 491 492
#ifdef CCISS_DEBUG
		printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
#endif
493
		c = h->cmd_pool + i;
L
Linus Torvalds 已提交
494
		memset(c, 0, sizeof(CommandList_struct));
495 496
		cmd_dma_handle = h->cmd_pool_dhandle
		    + i * sizeof(CommandList_struct);
L
Linus Torvalds 已提交
497 498
		c->err_info = h->errinfo_pool + i;
		memset(c->err_info, 0, sizeof(ErrorInfo_struct));
499 500 501
		err_dma_handle = h->errinfo_pool_dhandle
		    + i * sizeof(ErrorInfo_struct);
		h->nr_allocs++;
502 503

		c->cmdindex = i;
504
	}
L
Linus Torvalds 已提交
505 506

	c->busaddr = (__u32) cmd_dma_handle;
507
	temp64.val = (__u64) err_dma_handle;
L
Linus Torvalds 已提交
508 509 510 511
	c->ErrDesc.Addr.lower = temp64.val32.lower;
	c->ErrDesc.Addr.upper = temp64.val32.upper;
	c->ErrDesc.Len = sizeof(ErrorInfo_struct);

512 513
	c->ctlr = h->ctlr;
	return c;
L
Linus Torvalds 已提交
514 515
}

516 517
/*
 * Frees a command block that was previously allocated with cmd_alloc().
L
Linus Torvalds 已提交
518 519 520 521 522 523
 */
static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
{
	int i;
	u64bit temp64;

524
	if (!got_from_pool) {
L
Linus Torvalds 已提交
525 526
		temp64.val32.lower = c->ErrDesc.Addr.lower;
		temp64.val32.upper = c->ErrDesc.Addr.upper;
527 528 529 530 531
		pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct),
				    c->err_info, (dma_addr_t) temp64.val);
		pci_free_consistent(h->pdev, sizeof(CommandList_struct),
				    c, (dma_addr_t) c->busaddr);
	} else {
L
Linus Torvalds 已提交
532
		i = c - h->cmd_pool;
533 534 535 536
		clear_bit(i & (BITS_PER_LONG - 1),
			  h->cmd_pool_bits + (i / BITS_PER_LONG));
		h->nr_frees++;
	}
L
Linus Torvalds 已提交
537 538 539 540
}

static inline ctlr_info_t *get_host(struct gendisk *disk)
{
541
	return disk->queue->queuedata;
L
Linus Torvalds 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
}

static inline drive_info_struct *get_drv(struct gendisk *disk)
{
	return disk->private_data;
}

/*
 * Open.  Make sure the device is really there.
 */
static int cciss_open(struct inode *inode, struct file *filep)
{
	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
	drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);

#ifdef CCISS_DEBUG
	printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
559
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
560

561 562
	if (host->busy_initializing || drv->busy_configuring)
		return -EBUSY;
L
Linus Torvalds 已提交
563 564 565 566 567 568 569 570
	/*
	 * Root is allowed to open raw volume zero even if it's not configured
	 * so array config can still work. Root is also allowed to open any
	 * volume that has a LUN ID, so it can issue IOCTL to reread the
	 * disk information.  I don't think I really like this
	 * but I'm already using way to many device nodes to claim another one
	 * for "raw controller".
	 */
571
	if (drv->heads == 0) {
572
		if (iminor(inode) != 0) {	/* not node 0? */
L
Linus Torvalds 已提交
573 574
			/* if not node 0 make sure it is a partition = 0 */
			if (iminor(inode) & 0x0f) {
575
				return -ENXIO;
L
Linus Torvalds 已提交
576 577 578 579 580 581 582 583 584 585 586 587
				/* if it is, make sure we have a LUN ID */
			} else if (drv->LunID == 0) {
				return -ENXIO;
			}
		}
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
	}
	drv->usage_count++;
	host->usage_count++;
	return 0;
}
588

L
Linus Torvalds 已提交
589 590 591 592 593 594 595 596 597
/*
 * Close.  Sync first.
 */
static int cciss_release(struct inode *inode, struct file *filep)
{
	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
	drive_info_struct *drv = get_drv(inode->i_bdev->bd_disk);

#ifdef CCISS_DEBUG
598 599 600
	printk(KERN_DEBUG "cciss_release %s\n",
	       inode->i_bdev->bd_disk->disk_name);
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
601 602 603 604 605 606 607 608 609 610 611 612

	drv->usage_count--;
	host->usage_count--;
	return 0;
}

#ifdef CONFIG_COMPAT

static int do_ioctl(struct file *f, unsigned cmd, unsigned long arg)
{
	int ret;
	lock_kernel();
613
	ret = cciss_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
L
Linus Torvalds 已提交
614 615 616 617
	unlock_kernel();
	return ret;
}

618 619 620 621
static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
				  unsigned long arg);
static int cciss_ioctl32_big_passthru(struct file *f, unsigned cmd,
				      unsigned long arg);
L
Linus Torvalds 已提交
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652

static long cciss_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg)
{
	switch (cmd) {
	case CCISS_GETPCIINFO:
	case CCISS_GETINTINFO:
	case CCISS_SETINTINFO:
	case CCISS_GETNODENAME:
	case CCISS_SETNODENAME:
	case CCISS_GETHEARTBEAT:
	case CCISS_GETBUSTYPES:
	case CCISS_GETFIRMVER:
	case CCISS_GETDRIVVER:
	case CCISS_REVALIDVOLS:
	case CCISS_DEREGDISK:
	case CCISS_REGNEWDISK:
	case CCISS_REGNEWD:
	case CCISS_RESCANDISK:
	case CCISS_GETLUNINFO:
		return do_ioctl(f, cmd, arg);

	case CCISS_PASSTHRU32:
		return cciss_ioctl32_passthru(f, cmd, arg);
	case CCISS_BIG_PASSTHRU32:
		return cciss_ioctl32_big_passthru(f, cmd, arg);

	default:
		return -ENOIOCTLCMD;
	}
}

653 654
static int cciss_ioctl32_passthru(struct file *f, unsigned cmd,
				  unsigned long arg)
L
Linus Torvalds 已提交
655 656
{
	IOCTL32_Command_struct __user *arg32 =
657
	    (IOCTL32_Command_struct __user *) arg;
L
Linus Torvalds 已提交
658 659 660 661 662 663
	IOCTL_Command_struct arg64;
	IOCTL_Command_struct __user *p = compat_alloc_user_space(sizeof(arg64));
	int err;
	u32 cp;

	err = 0;
664 665 666 667 668 669 670 671 672
	err |=
	    copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
			   sizeof(arg64.LUN_info));
	err |=
	    copy_from_user(&arg64.Request, &arg32->Request,
			   sizeof(arg64.Request));
	err |=
	    copy_from_user(&arg64.error_info, &arg32->error_info,
			   sizeof(arg64.error_info));
L
Linus Torvalds 已提交
673 674 675 676 677 678 679 680
	err |= get_user(arg64.buf_size, &arg32->buf_size);
	err |= get_user(cp, &arg32->buf);
	arg64.buf = compat_ptr(cp);
	err |= copy_to_user(p, &arg64, sizeof(arg64));

	if (err)
		return -EFAULT;

681
	err = do_ioctl(f, CCISS_PASSTHRU, (unsigned long)p);
L
Linus Torvalds 已提交
682 683
	if (err)
		return err;
684 685 686
	err |=
	    copy_in_user(&arg32->error_info, &p->error_info,
			 sizeof(arg32->error_info));
L
Linus Torvalds 已提交
687 688 689 690 691
	if (err)
		return -EFAULT;
	return err;
}

692 693
static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd,
				      unsigned long arg)
L
Linus Torvalds 已提交
694 695
{
	BIG_IOCTL32_Command_struct __user *arg32 =
696
	    (BIG_IOCTL32_Command_struct __user *) arg;
L
Linus Torvalds 已提交
697
	BIG_IOCTL_Command_struct arg64;
698 699
	BIG_IOCTL_Command_struct __user *p =
	    compat_alloc_user_space(sizeof(arg64));
L
Linus Torvalds 已提交
700 701 702 703
	int err;
	u32 cp;

	err = 0;
704 705 706 707 708 709 710 711 712
	err |=
	    copy_from_user(&arg64.LUN_info, &arg32->LUN_info,
			   sizeof(arg64.LUN_info));
	err |=
	    copy_from_user(&arg64.Request, &arg32->Request,
			   sizeof(arg64.Request));
	err |=
	    copy_from_user(&arg64.error_info, &arg32->error_info,
			   sizeof(arg64.error_info));
L
Linus Torvalds 已提交
713 714 715 716 717 718 719
	err |= get_user(arg64.buf_size, &arg32->buf_size);
	err |= get_user(arg64.malloc_size, &arg32->malloc_size);
	err |= get_user(cp, &arg32->buf);
	arg64.buf = compat_ptr(cp);
	err |= copy_to_user(p, &arg64, sizeof(arg64));

	if (err)
720
		return -EFAULT;
L
Linus Torvalds 已提交
721

722
	err = do_ioctl(file, CCISS_BIG_PASSTHRU, (unsigned long)p);
L
Linus Torvalds 已提交
723 724
	if (err)
		return err;
725 726 727
	err |=
	    copy_in_user(&arg32->error_info, &p->error_info,
			 sizeof(arg32->error_info));
L
Linus Torvalds 已提交
728 729 730 731 732
	if (err)
		return -EFAULT;
	return err;
}
#endif
733 734 735 736 737 738 739 740 741 742 743 744 745 746

static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	drive_info_struct *drv = get_drv(bdev->bd_disk);

	if (!drv->cylinders)
		return -ENXIO;

	geo->heads = drv->heads;
	geo->sectors = drv->sectors;
	geo->cylinders = drv->cylinders;
	return 0;
}

L
Linus Torvalds 已提交
747
/*
748
 * ioctl
L
Linus Torvalds 已提交
749
 */
750 751
static int cciss_ioctl(struct inode *inode, struct file *filep,
		       unsigned int cmd, unsigned long arg)
L
Linus Torvalds 已提交
752 753 754 755 756 757 758 759 760 761
{
	struct block_device *bdev = inode->i_bdev;
	struct gendisk *disk = bdev->bd_disk;
	ctlr_info_t *host = get_host(disk);
	drive_info_struct *drv = get_drv(disk);
	int ctlr = host->ctlr;
	void __user *argp = (void __user *)arg;

#ifdef CCISS_DEBUG
	printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
762 763 764
#endif				/* CCISS_DEBUG */

	switch (cmd) {
L
Linus Torvalds 已提交
765
	case CCISS_GETPCIINFO:
766 767 768 769 770 771 772 773 774 775 776 777 778 779
		{
			cciss_pci_info_struct pciinfo;

			if (!arg)
				return -EINVAL;
			pciinfo.domain = pci_domain_nr(host->pdev->bus);
			pciinfo.bus = host->pdev->bus->number;
			pciinfo.dev_fn = host->pdev->devfn;
			pciinfo.board_id = host->board_id;
			if (copy_to_user
			    (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
780
	case CCISS_GETINTINFO:
781 782 783 784 785 786 787 788 789 790 791 792 793
		{
			cciss_coalint_struct intinfo;
			if (!arg)
				return -EINVAL;
			intinfo.delay =
			    readl(&host->cfgtable->HostWrite.CoalIntDelay);
			intinfo.count =
			    readl(&host->cfgtable->HostWrite.CoalIntCount);
			if (copy_to_user
			    (argp, &intinfo, sizeof(cciss_coalint_struct)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
794 795
	case CCISS_SETINTINFO:
		{
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
			cciss_coalint_struct intinfo;
			unsigned long flags;
			int i;

			if (!arg)
				return -EINVAL;
			if (!capable(CAP_SYS_ADMIN))
				return -EPERM;
			if (copy_from_user
			    (&intinfo, argp, sizeof(cciss_coalint_struct)))
				return -EFAULT;
			if ((intinfo.delay == 0) && (intinfo.count == 0))
			{
//                      printk("cciss_ioctl: delay and count cannot be 0\n");
				return -EINVAL;
			}
			spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
			/* Update the field, and then ring the doorbell */
			writel(intinfo.delay,
			       &(host->cfgtable->HostWrite.CoalIntDelay));
			writel(intinfo.count,
			       &(host->cfgtable->HostWrite.CoalIntCount));
			writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);

			for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
				if (!(readl(host->vaddr + SA5_DOORBELL)
				      & CFGTBL_ChangeReq))
					break;
				/* delay and try again */
				udelay(1000);
			}
			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
			if (i >= MAX_IOCTL_CONFIG_WAIT)
				return -EAGAIN;
			return 0;
L
Linus Torvalds 已提交
831 832
		}
	case CCISS_GETNODENAME:
833 834 835 836 837 838 839 840 841 842 843 844 845
		{
			NodeName_type NodeName;
			int i;

			if (!arg)
				return -EINVAL;
			for (i = 0; i < 16; i++)
				NodeName[i] =
				    readb(&host->cfgtable->ServerName[i]);
			if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
846
	case CCISS_SETNODENAME:
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
		{
			NodeName_type NodeName;
			unsigned long flags;
			int i;

			if (!arg)
				return -EINVAL;
			if (!capable(CAP_SYS_ADMIN))
				return -EPERM;

			if (copy_from_user
			    (NodeName, argp, sizeof(NodeName_type)))
				return -EFAULT;

			spin_lock_irqsave(CCISS_LOCK(ctlr), flags);

			/* Update the field, and then ring the doorbell */
			for (i = 0; i < 16; i++)
				writeb(NodeName[i],
				       &host->cfgtable->ServerName[i]);

			writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);

			for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
				if (!(readl(host->vaddr + SA5_DOORBELL)
				      & CFGTBL_ChangeReq))
					break;
				/* delay and try again */
				udelay(1000);
			}
			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
			if (i >= MAX_IOCTL_CONFIG_WAIT)
				return -EAGAIN;
			return 0;
		}
L
Linus Torvalds 已提交
882 883

	case CCISS_GETHEARTBEAT:
884 885 886 887 888 889 890 891 892 893 894
		{
			Heartbeat_type heartbeat;

			if (!arg)
				return -EINVAL;
			heartbeat = readl(&host->cfgtable->HeartBeat);
			if (copy_to_user
			    (argp, &heartbeat, sizeof(Heartbeat_type)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
895
	case CCISS_GETBUSTYPES:
896 897 898 899 900 901 902 903 904 905 906
		{
			BusTypes_type BusTypes;

			if (!arg)
				return -EINVAL;
			BusTypes = readl(&host->cfgtable->BusTypes);
			if (copy_to_user
			    (argp, &BusTypes, sizeof(BusTypes_type)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
907
	case CCISS_GETFIRMVER:
908 909
		{
			FirmwareVer_type firmware;
L
Linus Torvalds 已提交
910

911 912 913
			if (!arg)
				return -EINVAL;
			memcpy(firmware, host->firm_ver, 4);
L
Linus Torvalds 已提交
914

915 916 917 918 919 920 921 922
			if (copy_to_user
			    (argp, firmware, sizeof(FirmwareVer_type)))
				return -EFAULT;
			return 0;
		}
	case CCISS_GETDRIVVER:
		{
			DriverVer_type DriverVer = DRIVER_VERSION;
L
Linus Torvalds 已提交
923

924 925
			if (!arg)
				return -EINVAL;
L
Linus Torvalds 已提交
926

927 928 929 930 931
			if (copy_to_user
			    (argp, &DriverVer, sizeof(DriverVer_type)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
932 933

	case CCISS_REVALIDVOLS:
934
		return rebuild_lun_table(host, NULL);
935 936 937 938 939 940 941 942 943 944 945 946

	case CCISS_GETLUNINFO:{
			LogvolInfo_struct luninfo;

			luninfo.LunID = drv->LunID;
			luninfo.num_opens = drv->usage_count;
			luninfo.num_parts = 0;
			if (copy_to_user(argp, &luninfo,
					 sizeof(LogvolInfo_struct)))
				return -EFAULT;
			return 0;
		}
L
Linus Torvalds 已提交
947
	case CCISS_DEREGDISK:
948
		return rebuild_lun_table(host, disk);
L
Linus Torvalds 已提交
949 950

	case CCISS_REGNEWD:
951
		return rebuild_lun_table(host, NULL);
L
Linus Torvalds 已提交
952 953 954

	case CCISS_PASSTHRU:
		{
955 956 957 958 959
			IOCTL_Command_struct iocommand;
			CommandList_struct *c;
			char *buff = NULL;
			u64bit temp64;
			unsigned long flags;
960
			DECLARE_COMPLETION_ONSTACK(wait);
L
Linus Torvalds 已提交
961

962 963
			if (!arg)
				return -EINVAL;
L
Linus Torvalds 已提交
964

965 966
			if (!capable(CAP_SYS_RAWIO))
				return -EPERM;
L
Linus Torvalds 已提交
967

968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
			if (copy_from_user
			    (&iocommand, argp, sizeof(IOCTL_Command_struct)))
				return -EFAULT;
			if ((iocommand.buf_size < 1) &&
			    (iocommand.Request.Type.Direction != XFER_NONE)) {
				return -EINVAL;
			}
#if 0				/* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
			/* Check kmalloc limits */
			if (iocommand.buf_size > 128000)
				return -EINVAL;
#endif
			if (iocommand.buf_size > 0) {
				buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
				if (buff == NULL)
					return -EFAULT;
			}
			if (iocommand.Request.Type.Direction == XFER_WRITE) {
				/* Copy the data into the buffer we created */
				if (copy_from_user
				    (buff, iocommand.buf, iocommand.buf_size)) {
					kfree(buff);
					return -EFAULT;
				}
			} else {
				memset(buff, 0, iocommand.buf_size);
			}
			if ((c = cmd_alloc(host, 0)) == NULL) {
				kfree(buff);
				return -ENOMEM;
			}
			// Fill in the command type
			c->cmd_type = CMD_IOCTL_PEND;
			// Fill in Command Header
			c->Header.ReplyQueue = 0;	// unused in simple mode
			if (iocommand.buf_size > 0)	// buffer to fill
			{
				c->Header.SGList = 1;
				c->Header.SGTotal = 1;
			} else	// no buffers to fill
			{
				c->Header.SGList = 0;
				c->Header.SGTotal = 0;
			}
			c->Header.LUN = iocommand.LUN_info;
			c->Header.Tag.lower = c->busaddr;	// use the kernel address the cmd block for tag
L
Linus Torvalds 已提交
1014

1015 1016
			// Fill in Request block
			c->Request = iocommand.Request;
L
Linus Torvalds 已提交
1017

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
			// Fill in the scatter gather information
			if (iocommand.buf_size > 0) {
				temp64.val = pci_map_single(host->pdev, buff,
					iocommand.buf_size,
					PCI_DMA_BIDIRECTIONAL);
				c->SG[0].Addr.lower = temp64.val32.lower;
				c->SG[0].Addr.upper = temp64.val32.upper;
				c->SG[0].Len = iocommand.buf_size;
				c->SG[0].Ext = 0;	// we are not chaining
			}
			c->waiting = &wait;

			/* Put the request on the tail of the request queue */
			spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
			addQ(&host->reqQ, c);
			host->Qdepth++;
			start_io(host);
			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);

			wait_for_completion(&wait);

			/* unlock the buffers from DMA */
			temp64.val32.lower = c->SG[0].Addr.lower;
			temp64.val32.upper = c->SG[0].Addr.upper;
			pci_unmap_single(host->pdev, (dma_addr_t) temp64.val,
					 iocommand.buf_size,
					 PCI_DMA_BIDIRECTIONAL);

			/* Copy the error information out */
			iocommand.error_info = *(c->err_info);
			if (copy_to_user
			    (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
				kfree(buff);
L
Linus Torvalds 已提交
1051 1052 1053
				cmd_free(host, c, 0);
				return -EFAULT;
			}
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066

			if (iocommand.Request.Type.Direction == XFER_READ) {
				/* Copy the data out of the buffer we created */
				if (copy_to_user
				    (iocommand.buf, buff, iocommand.buf_size)) {
					kfree(buff);
					cmd_free(host, c, 0);
					return -EFAULT;
				}
			}
			kfree(buff);
			cmd_free(host, c, 0);
			return 0;
L
Linus Torvalds 已提交
1067
		}
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
	case CCISS_BIG_PASSTHRU:{
			BIG_IOCTL_Command_struct *ioc;
			CommandList_struct *c;
			unsigned char **buff = NULL;
			int *buff_size = NULL;
			u64bit temp64;
			unsigned long flags;
			BYTE sg_used = 0;
			int status = 0;
			int i;
1078
			DECLARE_COMPLETION_ONSTACK(wait);
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
			__u32 left;
			__u32 sz;
			BYTE __user *data_ptr;

			if (!arg)
				return -EINVAL;
			if (!capable(CAP_SYS_RAWIO))
				return -EPERM;
			ioc = (BIG_IOCTL_Command_struct *)
			    kmalloc(sizeof(*ioc), GFP_KERNEL);
			if (!ioc) {
				status = -ENOMEM;
				goto cleanup1;
			}
			if (copy_from_user(ioc, argp, sizeof(*ioc))) {
				status = -EFAULT;
				goto cleanup1;
			}
			if ((ioc->buf_size < 1) &&
			    (ioc->Request.Type.Direction != XFER_NONE)) {
L
Linus Torvalds 已提交
1099 1100
				status = -EINVAL;
				goto cleanup1;
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
			}
			/* Check kmalloc limits  using all SGs */
			if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
				status = -EINVAL;
				goto cleanup1;
			}
			if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
				status = -EINVAL;
				goto cleanup1;
			}
			buff =
			    kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
			if (!buff) {
L
Linus Torvalds 已提交
1114 1115 1116
				status = -ENOMEM;
				goto cleanup1;
			}
1117
			buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
						   GFP_KERNEL);
			if (!buff_size) {
				status = -ENOMEM;
				goto cleanup1;
			}
			left = ioc->buf_size;
			data_ptr = ioc->buf;
			while (left) {
				sz = (left >
				      ioc->malloc_size) ? ioc->
				    malloc_size : left;
				buff_size[sg_used] = sz;
				buff[sg_used] = kmalloc(sz, GFP_KERNEL);
				if (buff[sg_used] == NULL) {
L
Linus Torvalds 已提交
1132
					status = -ENOMEM;
1133 1134
					goto cleanup1;
				}
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
				if (ioc->Request.Type.Direction == XFER_WRITE) {
					if (copy_from_user
					    (buff[sg_used], data_ptr, sz)) {
						status = -ENOMEM;
						goto cleanup1;
					}
				} else {
					memset(buff[sg_used], 0, sz);
				}
				left -= sz;
				data_ptr += sz;
				sg_used++;
			}
			if ((c = cmd_alloc(host, 0)) == NULL) {
				status = -ENOMEM;
				goto cleanup1;
			}
			c->cmd_type = CMD_IOCTL_PEND;
			c->Header.ReplyQueue = 0;

			if (ioc->buf_size > 0) {
				c->Header.SGList = sg_used;
				c->Header.SGTotal = sg_used;
L
Linus Torvalds 已提交
1158
			} else {
1159 1160
				c->Header.SGList = 0;
				c->Header.SGTotal = 0;
L
Linus Torvalds 已提交
1161
			}
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194
			c->Header.LUN = ioc->LUN_info;
			c->Header.Tag.lower = c->busaddr;

			c->Request = ioc->Request;
			if (ioc->buf_size > 0) {
				int i;
				for (i = 0; i < sg_used; i++) {
					temp64.val =
					    pci_map_single(host->pdev, buff[i],
						    buff_size[i],
						    PCI_DMA_BIDIRECTIONAL);
					c->SG[i].Addr.lower =
					    temp64.val32.lower;
					c->SG[i].Addr.upper =
					    temp64.val32.upper;
					c->SG[i].Len = buff_size[i];
					c->SG[i].Ext = 0;	/* we are not chaining */
				}
			}
			c->waiting = &wait;
			/* Put the request on the tail of the request queue */
			spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
			addQ(&host->reqQ, c);
			host->Qdepth++;
			start_io(host);
			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
			wait_for_completion(&wait);
			/* unlock the buffers from DMA */
			for (i = 0; i < sg_used; i++) {
				temp64.val32.lower = c->SG[i].Addr.lower;
				temp64.val32.upper = c->SG[i].Addr.upper;
				pci_unmap_single(host->pdev,
					(dma_addr_t) temp64.val, buff_size[i],
L
Linus Torvalds 已提交
1195 1196
					PCI_DMA_BIDIRECTIONAL);
			}
1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
			/* Copy the error information out */
			ioc->error_info = *(c->err_info);
			if (copy_to_user(argp, ioc, sizeof(*ioc))) {
				cmd_free(host, c, 0);
				status = -EFAULT;
				goto cleanup1;
			}
			if (ioc->Request.Type.Direction == XFER_READ) {
				/* Copy the data out of the buffer we created */
				BYTE __user *ptr = ioc->buf;
				for (i = 0; i < sg_used; i++) {
					if (copy_to_user
					    (ptr, buff[i], buff_size[i])) {
						cmd_free(host, c, 0);
						status = -EFAULT;
						goto cleanup1;
					}
					ptr += buff_size[i];
L
Linus Torvalds 已提交
1215 1216
				}
			}
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
			cmd_free(host, c, 0);
			status = 0;
		      cleanup1:
			if (buff) {
				for (i = 0; i < sg_used; i++)
					kfree(buff[i]);
				kfree(buff);
			}
			kfree(buff_size);
			kfree(ioc);
			return status;
L
Linus Torvalds 已提交
1228
		}
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240

	/* scsi_cmd_ioctl handles these, below, though some are not */
	/* very meaningful for cciss.  SG_IO is the main one people want. */

	case SG_GET_VERSION_NUM:
	case SG_SET_TIMEOUT:
	case SG_GET_TIMEOUT:
	case SG_GET_RESERVED_SIZE:
	case SG_SET_RESERVED_SIZE:
	case SG_EMULATED_HOST:
	case SG_IO:
	case SCSI_IOCTL_SEND_COMMAND:
1241
		return scsi_cmd_ioctl(filep, disk->queue, disk, cmd, argp);
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252

	/* scsi_cmd_ioctl would normally handle these, below, but */
	/* they aren't a good fit for cciss, as CD-ROMs are */
	/* not supported, and we don't have any bus/target/lun */
	/* which we present to the kernel. */

	case CDROM_SEND_PACKET:
	case CDROMCLOSETRAY:
	case CDROMEJECT:
	case SCSI_IOCTL_GET_IDLUN:
	case SCSI_IOCTL_GET_BUS_NUMBER:
L
Linus Torvalds 已提交
1253 1254 1255 1256 1257
	default:
		return -ENOTTY;
	}
}

1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
static void cciss_check_queues(ctlr_info_t *h)
{
	int start_queue = h->next_to_run;
	int i;

	/* check to see if we have maxed out the number of commands that can
	 * be placed on the queue.  If so then exit.  We do this check here
	 * in case the interrupt we serviced was from an ioctl and did not
	 * free any new commands.
	 */
1268
	if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds)
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
		return;

	/* We have room on the queue for more commands.  Now we need to queue
	 * them up.  We will also keep track of the next queue to run so
	 * that every queue gets a chance to be started first.
	 */
	for (i = 0; i < h->highest_lun + 1; i++) {
		int curr_queue = (start_queue + i) % (h->highest_lun + 1);
		/* make sure the disk has been added and the drive is real
		 * because this can be called from the middle of init_one.
		 */
		if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads))
			continue;
		blk_start_queue(h->gendisk[curr_queue]->queue);

		/* check to see if we have maxed out the number of commands
		 * that can be placed on the queue.
		 */
1287
		if ((find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds)) == h->nr_cmds) {
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
			if (curr_queue == start_queue) {
				h->next_to_run =
				    (start_queue + 1) % (h->highest_lun + 1);
				break;
			} else {
				h->next_to_run = curr_queue;
				break;
			}
		} else {
			curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
		}
	}
}

1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
static void cciss_softirq_done(struct request *rq)
{
	CommandList_struct *cmd = rq->completion_data;
	ctlr_info_t *h = hba[cmd->ctlr];
	unsigned long flags;
	u64bit temp64;
	int i, ddir;

	if (cmd->Request.Type.Direction == XFER_READ)
		ddir = PCI_DMA_FROMDEVICE;
	else
		ddir = PCI_DMA_TODEVICE;

	/* command did not need to be retried */
	/* unmap the DMA mapping for all the scatter gather elements */
1317
	for (i = 0; i < cmd->Header.SGList; i++) {
1318 1319 1320 1321 1322 1323 1324
		temp64.val32.lower = cmd->SG[i].Addr.lower;
		temp64.val32.upper = cmd->SG[i].Addr.upper;
		pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
	}

#ifdef CCISS_DEBUG
	printk("Done with %p\n", rq);
1325
#endif				/* CCISS_DEBUG */
1326

1327 1328 1329
	if (blk_end_request(rq, (rq->errors == 0) ? 0 : -EIO, blk_rq_bytes(rq)))
		BUG();

1330
	spin_lock_irqsave(&h->lock, flags);
1331
	cmd_free(h, cmd, 1);
1332
	cciss_check_queues(h);
1333 1334 1335
	spin_unlock_irqrestore(&h->lock, flags);
}

1336 1337 1338 1339 1340 1341 1342
/* This function will check the usage_count of the drive to be updated/added.
 * If the usage_count is zero then the drive information will be updated and
 * the disk will be re-registered with the kernel.  If not then it will be
 * left alone for the next reboot.  The exception to this is disk 0 which
 * will always be left registered with the kernel since it is also the
 * controller node.  Any changes to disk 0 will show up on the next
 * reboot.
1343
 */
1344
static void cciss_update_drive_info(int ctlr, int drv_index)
1345
{
1346 1347 1348 1349
	ctlr_info_t *h = hba[ctlr];
	struct gendisk *disk;
	InquiryData_struct *inq_buff = NULL;
	unsigned int block_size;
1350
	sector_t total_size;
1351 1352 1353
	unsigned long flags = 0;
	int ret = 0;

1354 1355
	/* if the disk already exists then deregister it before proceeding */
	if (h->drv[drv_index].raid_level != -1) {
1356 1357 1358
		spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
		h->drv[drv_index].busy_configuring = 1;
		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1359 1360 1361 1362

		/* deregister_disk sets h->drv[drv_index].queue = NULL */
		/* which keeps the interrupt handler from starting */
		/* the queue. */
1363
		ret = deregister_disk(h->gendisk[drv_index],
1364
				      &h->drv[drv_index], 0);
1365 1366 1367 1368 1369 1370 1371
		h->drv[drv_index].busy_configuring = 0;
	}

	/* If the disk is in use return */
	if (ret)
		return;

1372
	/* Get information about the disk and modify the driver structure */
1373
	inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1374 1375 1376
	if (inq_buff == NULL)
		goto mem_msg;

1377 1378 1379 1380 1381 1382 1383
 	/* testing to see if 16-byte CDBs are already being used */
 	if (h->cciss_read == CCISS_READ_16) {
 		cciss_read_capacity_16(h->ctlr, drv_index, 1,
 			&total_size, &block_size);
 		goto geo_inq;
 	}

1384
	cciss_read_capacity(ctlr, drv_index, 1,
1385
			    &total_size, &block_size);
1386

1387 1388 1389
  	/* if read_capacity returns all F's this volume is >2TB in size */
  	/* so we switch to 16-byte CDB's for all read/write ops */
  	if (total_size == 0xFFFFFFFFULL) {
1390 1391 1392 1393 1394 1395 1396 1397
		cciss_read_capacity_16(ctlr, drv_index, 1,
		&total_size, &block_size);
		h->cciss_read = CCISS_READ_16;
		h->cciss_write = CCISS_WRITE_16;
	} else {
		h->cciss_read = CCISS_READ_10;
		h->cciss_write = CCISS_WRITE_10;
	}
1398
geo_inq:
1399
	cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
1400
			       inq_buff, &h->drv[drv_index]);
1401 1402 1403 1404 1405 1406

	++h->num_luns;
	disk = h->gendisk[drv_index];
	set_capacity(disk, h->drv[drv_index].nr_blocks);

	/* if it's the controller it's already added */
1407
	if (drv_index) {
1408
		disk->queue = blk_init_queue(do_cciss_request, &h->lock);
1409 1410 1411 1412 1413
		sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index);
		disk->major = h->major;
		disk->first_minor = drv_index << NWD_SHIFT;
		disk->fops = &cciss_fops;
		disk->private_data = &h->drv[drv_index];
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423

		/* Set up queue information */
		blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);

		/* This is a hardware imposed limit. */
		blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);

		/* This is a limit in the driver and could be eliminated. */
		blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);

1424
		blk_queue_max_sectors(disk->queue, h->cciss_max_sectors);
1425

1426 1427
		blk_queue_softirq_done(disk->queue, cciss_softirq_done);

1428 1429 1430
		disk->queue->queuedata = hba[ctlr];

		blk_queue_hardsect_size(disk->queue,
1431
					hba[ctlr]->drv[drv_index].block_size);
1432

1433 1434 1435 1436
		/* Make sure all queue data is written out before */
		/* setting h->drv[drv_index].queue, as setting this */
		/* allows the interrupt handler to start the queue */
		wmb();
1437 1438 1439 1440
		h->drv[drv_index].queue = disk->queue;
		add_disk(disk);
	}

1441
      freeret:
1442 1443
	kfree(inq_buff);
	return;
1444
      mem_msg:
1445 1446 1447 1448 1449 1450 1451 1452 1453
	printk(KERN_ERR "cciss: out of memory\n");
	goto freeret;
}

/* This function will find the first index of the controllers drive array
 * that has a -1 for the raid_level and will return that index.  This is
 * where new drives will be added.  If the index to be returned is greater
 * than the highest_lun index for the controller then highest_lun is set
 * to this new index.  If there are no available indexes then -1 is returned.
1454
 */
1455 1456 1457 1458
static int cciss_find_free_drive_index(int ctlr)
{
	int i;

1459 1460
	for (i = 0; i < CISS_MAX_LUN; i++) {
		if (hba[ctlr]->drv[i].raid_level == -1) {
1461 1462 1463 1464 1465 1466 1467 1468 1469
			if (i > hba[ctlr]->highest_lun)
				hba[ctlr]->highest_lun = i;
			return i;
		}
	}
	return -1;
}

/* This function will add and remove logical drives from the Logical
1470
 * drive array of the controller and maintain persistency of ordering
1471 1472 1473 1474 1475 1476 1477
 * so that mount points are preserved until the next reboot.  This allows
 * for the removal of logical drives in the middle of the drive array
 * without a re-ordering of those drives.
 * INPUT
 * h		= The controller to perform the operations on
 * del_disk	= The disk to remove if specified.  If the value given
 *		  is NULL then no disk is removed.
1478
 */
1479
static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
L
Linus Torvalds 已提交
1480
{
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
	int ctlr = h->ctlr;
	int num_luns;
	ReportLunData_struct *ld_buff = NULL;
	drive_info_struct *drv = NULL;
	int return_code;
	int listlength = 0;
	int i;
	int drv_found;
	int drv_index = 0;
	__u32 lunid = 0;
L
Linus Torvalds 已提交
1491
	unsigned long flags;
1492 1493 1494

	/* Set busy_configuring flag for this operation */
	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1495
	if (h->busy_configuring) {
1496 1497 1498 1499 1500 1501 1502 1503 1504
		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
		return -EBUSY;
	}
	h->busy_configuring = 1;

	/* if del_disk is NULL then we are being called to add a new disk
	 * and update the logical drive table.  If it is not NULL then
	 * we will check if the disk is in use or not.
	 */
1505
	if (del_disk != NULL) {
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522
		drv = get_drv(del_disk);
		drv->busy_configuring = 1;
		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
		return_code = deregister_disk(del_disk, drv, 1);
		drv->busy_configuring = 0;
		h->busy_configuring = 0;
		return return_code;
	} else {
		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
		if (!capable(CAP_SYS_RAWIO))
			return -EPERM;

		ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
		if (ld_buff == NULL)
			goto mem_msg;

		return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
1523 1524 1525 1526
					      sizeof(ReportLunData_struct), 0,
					      0, 0, TYPE_CMD);

		if (return_code == IO_OK) {
1527
			listlength =
A
Al Viro 已提交
1528
				be32_to_cpu(*(__be32 *) ld_buff->LUNListLength);
1529
		} else {	/* reading number of logical volumes failed */
1530
			printk(KERN_WARNING "cciss: report logical volume"
1531
			       " command failed\n");
1532 1533 1534 1535 1536
			listlength = 0;
			goto freeret;
		}

		num_luns = listlength / 8;	/* 8 bytes per entry */
1537
		if (num_luns > CISS_MAX_LUN) {
1538 1539
			num_luns = CISS_MAX_LUN;
			printk(KERN_WARNING "cciss: more luns configured"
1540 1541
			       " on controller than can be handled by"
			       " this driver.\n");
1542 1543 1544
		}

		/* Compare controller drive array to drivers drive array.
1545 1546 1547 1548
		 * Check for updates in the drive information and any new drives
		 * on the controller.
		 */
		for (i = 0; i < num_luns; i++) {
1549 1550 1551 1552
			int j;

			drv_found = 0;

1553 1554 1555 1556 1557 1558 1559
			lunid = (0xff &
				 (unsigned int)(ld_buff->LUN[i][3])) << 24;
			lunid |= (0xff &
				  (unsigned int)(ld_buff->LUN[i][2])) << 16;
			lunid |= (0xff &
				  (unsigned int)(ld_buff->LUN[i][1])) << 8;
			lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
1560 1561 1562 1563 1564

			/* Find if the LUN is already in the drive array
			 * of the controller.  If so then update its info
			 * if not is use.  If it does not exist then find
			 * the first free index and add it.
1565 1566 1567
			 */
			for (j = 0; j <= h->highest_lun; j++) {
				if (h->drv[j].LunID == lunid) {
1568 1569 1570 1571 1572 1573
					drv_index = j;
					drv_found = 1;
				}
			}

			/* check if the drive was found already in the array */
1574
			if (!drv_found) {
1575 1576 1577 1578
				drv_index = cciss_find_free_drive_index(ctlr);
				if (drv_index == -1)
					goto freeret;

1579 1580 1581 1582 1583 1584 1585 1586
				/*Check if the gendisk needs to be allocated */
				if (!h->gendisk[drv_index]){
					h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT);
					if (!h->gendisk[drv_index]){
						printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index);
						goto mem_msg;
					}
				}
1587 1588 1589
			}
			h->drv[drv_index].LunID = lunid;
			cciss_update_drive_info(ctlr, drv_index);
1590 1591
		}		/* end for */
	}			/* end else */
1592

1593
      freeret:
1594 1595 1596 1597 1598
	kfree(ld_buff);
	h->busy_configuring = 0;
	/* We return -1 here to tell the ACU that we have registered/updated
	 * all of the drives that we can and to keep it from calling us
	 * additional times.
1599
	 */
1600
	return -1;
1601
      mem_msg:
1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
	printk(KERN_ERR "cciss: out of memory\n");
	goto freeret;
}

/* This function will deregister the disk and it's queue from the
 * kernel.  It must be called with the controller lock held and the
 * drv structures busy_configuring flag set.  It's parameters are:
 *
 * disk = This is the disk to be deregistered
 * drv  = This is the drive_info_struct associated with the disk to be
 *        deregistered.  It contains information about the disk used
 *        by the driver.
 * clear_all = This flag determines whether or not the disk information
 *             is going to be completely cleared out and the highest_lun
 *             reset.  Sometimes we want to clear out information about
1617
 *             the disk in preparation for re-adding it.  In this case
1618 1619 1620 1621 1622 1623
 *             the highest_lun should be left unchanged and the LunID
 *             should not be cleared.
*/
static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
			   int clear_all)
{
1624
	int i;
L
Linus Torvalds 已提交
1625 1626 1627 1628 1629 1630
	ctlr_info_t *h = get_host(disk);

	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;

	/* make sure logical volume is NOT is use */
1631 1632 1633 1634 1635
	if (clear_all || (h->gendisk[0] == disk)) {
		if (drv->usage_count > 1)
			return -EBUSY;
	} else if (drv->usage_count > 0)
		return -EBUSY;
L
Linus Torvalds 已提交
1636

1637 1638 1639
	/* invalidate the devices and deregister the disk.  If it is disk
	 * zero do not deregister it but just zero out it's values.  This
	 * allows us to delete disk zero but keep the controller registered.
1640 1641
	 */
	if (h->gendisk[0] != disk) {
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663
		struct request_queue *q = disk->queue;
		if (disk->flags & GENHD_FL_UP)
			del_gendisk(disk);
		if (q) {
			blk_cleanup_queue(q);
			/* Set drv->queue to NULL so that we do not try
			 * to call blk_start_queue on this queue in the
			 * interrupt handler
			 */
			drv->queue = NULL;
		}
		/* If clear_all is set then we are deleting the logical
		 * drive, not just refreshing its info.  For drives
		 * other than disk 0 we will call put_disk.  We do not
		 * do this for disk 0 as we need it to be able to
		 * configure the controller.
		*/
		if (clear_all){
			/* This isn't pretty, but we need to find the
			 * disk in our array and NULL our the pointer.
			 * This is so that we will call alloc_disk if
			 * this index is used again later.
1664
			*/
1665 1666 1667 1668
			for (i=0; i < CISS_MAX_LUN; i++){
				if(h->gendisk[i] == disk){
					h->gendisk[i] = NULL;
					break;
1669 1670
				}
			}
1671
			put_disk(disk);
1672
		}
1673 1674
	} else {
		set_capacity(disk, 0);
1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686
	}

	--h->num_luns;
	/* zero out the disk size info */
	drv->nr_blocks = 0;
	drv->block_size = 0;
	drv->heads = 0;
	drv->sectors = 0;
	drv->cylinders = 0;
	drv->raid_level = -1;	/* This can be used as a flag variable to
				 * indicate that this element of the drive
				 * array is free.
1687 1688 1689 1690 1691 1692 1693 1694 1695
				 */

	if (clear_all) {
		/* check to see if it was the last disk */
		if (drv == h->drv + h->highest_lun) {
			/* if so, find the new hightest lun */
			int i, newhighest = -1;
			for (i = 0; i < h->highest_lun; i++) {
				/* if the disk has size > 0, it is available */
1696
				if (h->drv[i].heads)
1697 1698 1699
					newhighest = i;
			}
			h->highest_lun = newhighest;
L
Linus Torvalds 已提交
1700
		}
1701

1702
		drv->LunID = 0;
1703
	}
1704
	return 0;
L
Linus Torvalds 已提交
1705
}
1706

1707 1708 1709 1710 1711
static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_t size, unsigned int use_unit_num,	/* 0: address the controller,
															   1: address logical volume log_unit,
															   2: periph device address is scsi3addr */
		    unsigned int log_unit, __u8 page_code,
		    unsigned char *scsi3addr, int cmd_type)
L
Linus Torvalds 已提交
1712
{
1713
	ctlr_info_t *h = hba[ctlr];
L
Linus Torvalds 已提交
1714 1715 1716 1717 1718
	u64bit buff_dma_handle;
	int status = IO_OK;

	c->cmd_type = CMD_IOCTL_PEND;
	c->Header.ReplyQueue = 0;
1719
	if (buff != NULL) {
L
Linus Torvalds 已提交
1720
		c->Header.SGList = 1;
1721
		c->Header.SGTotal = 1;
L
Linus Torvalds 已提交
1722 1723
	} else {
		c->Header.SGList = 0;
1724
		c->Header.SGTotal = 0;
L
Linus Torvalds 已提交
1725 1726 1727 1728 1729
	}
	c->Header.Tag.lower = c->busaddr;

	c->Request.Type.Type = cmd_type;
	if (cmd_type == TYPE_CMD) {
1730 1731
		switch (cmd) {
		case CISS_INQUIRY:
L
Linus Torvalds 已提交
1732
			/* If the logical unit number is 0 then, this is going
1733 1734 1735 1736 1737 1738
			   to controller so It's a physical command
			   mode = 0 target = 0.  So we have nothing to write.
			   otherwise, if use_unit_num == 1,
			   mode = 1(volume set addressing) target = LUNID
			   otherwise, if use_unit_num == 2,
			   mode = 0(periph dev addr) target = scsi3addr */
L
Linus Torvalds 已提交
1739
			if (use_unit_num == 1) {
1740 1741 1742
				c->Header.LUN.LogDev.VolId =
				    h->drv[log_unit].LunID;
				c->Header.LUN.LogDev.Mode = 1;
L
Linus Torvalds 已提交
1743
			} else if (use_unit_num == 2) {
1744 1745
				memcpy(c->Header.LUN.LunAddrBytes, scsi3addr,
				       8);
L
Linus Torvalds 已提交
1746 1747 1748
				c->Header.LUN.LogDev.Mode = 0;
			}
			/* are we trying to read a vital product page */
1749
			if (page_code != 0) {
L
Linus Torvalds 已提交
1750 1751 1752 1753
				c->Request.CDB[1] = 0x01;
				c->Request.CDB[2] = page_code;
			}
			c->Request.CDBLen = 6;
1754
			c->Request.Type.Attribute = ATTR_SIMPLE;
L
Linus Torvalds 已提交
1755 1756
			c->Request.Type.Direction = XFER_READ;
			c->Request.Timeout = 0;
1757 1758 1759
			c->Request.CDB[0] = CISS_INQUIRY;
			c->Request.CDB[4] = size & 0xFF;
			break;
L
Linus Torvalds 已提交
1760 1761
		case CISS_REPORT_LOG:
		case CISS_REPORT_PHYS:
1762
			/* Talking to controller so It's a physical command
L
Linus Torvalds 已提交
1763
			   mode = 00 target = 0.  Nothing to write.
1764
			 */
L
Linus Torvalds 已提交
1765 1766 1767 1768 1769
			c->Request.CDBLen = 12;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_READ;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = cmd;
1770
			c->Request.CDB[6] = (size >> 24) & 0xFF;	//MSB
L
Linus Torvalds 已提交
1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783
			c->Request.CDB[7] = (size >> 16) & 0xFF;
			c->Request.CDB[8] = (size >> 8) & 0xFF;
			c->Request.CDB[9] = size & 0xFF;
			break;

		case CCISS_READ_CAPACITY:
			c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
			c->Header.LUN.LogDev.Mode = 1;
			c->Request.CDBLen = 10;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_READ;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = cmd;
1784
			break;
1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800
		case CCISS_READ_CAPACITY_16:
			c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
			c->Header.LUN.LogDev.Mode = 1;
			c->Request.CDBLen = 16;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_READ;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = cmd;
			c->Request.CDB[1] = 0x10;
			c->Request.CDB[10] = (size >> 24) & 0xFF;
			c->Request.CDB[11] = (size >> 16) & 0xFF;
			c->Request.CDB[12] = (size >> 8) & 0xFF;
			c->Request.CDB[13] = size & 0xFF;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = cmd;
			break;
L
Linus Torvalds 已提交
1801 1802 1803 1804 1805 1806 1807
		case CCISS_CACHE_FLUSH:
			c->Request.CDBLen = 12;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_WRITE;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = BMIC_WRITE;
			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
1808
			break;
L
Linus Torvalds 已提交
1809 1810
		default:
			printk(KERN_WARNING
1811
			       "cciss%d:  Unknown Command 0x%c\n", ctlr, cmd);
1812
			return IO_ERROR;
L
Linus Torvalds 已提交
1813 1814 1815
		}
	} else if (cmd_type == TYPE_MSG) {
		switch (cmd) {
1816
		case 0:	/* ABORT message */
1817 1818 1819 1820
			c->Request.CDBLen = 12;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_WRITE;
			c->Request.Timeout = 0;
1821 1822
			c->Request.CDB[0] = cmd;	/* abort */
			c->Request.CDB[1] = 0;	/* abort a command */
1823 1824 1825
			/* buff contains the tag of the command to abort */
			memcpy(&c->Request.CDB[4], buff, 8);
			break;
1826
		case 1:	/* RESET message */
1827 1828 1829 1830 1831
			c->Request.CDBLen = 12;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_WRITE;
			c->Request.Timeout = 0;
			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
1832 1833
			c->Request.CDB[0] = cmd;	/* reset */
			c->Request.CDB[1] = 0x04;	/* reset a LUN */
1834
			break;
L
Linus Torvalds 已提交
1835 1836 1837 1838 1839 1840 1841 1842 1843
		case 3:	/* No-Op message */
			c->Request.CDBLen = 1;
			c->Request.Type.Attribute = ATTR_SIMPLE;
			c->Request.Type.Direction = XFER_WRITE;
			c->Request.Timeout = 0;
			c->Request.CDB[0] = cmd;
			break;
		default:
			printk(KERN_WARNING
1844
			       "cciss%d: unknown message type %d\n", ctlr, cmd);
L
Linus Torvalds 已提交
1845 1846 1847 1848
			return IO_ERROR;
		}
	} else {
		printk(KERN_WARNING
1849
		       "cciss%d: unknown command type %d\n", ctlr, cmd_type);
L
Linus Torvalds 已提交
1850 1851 1852 1853 1854
		return IO_ERROR;
	}
	/* Fill in the scatter gather information */
	if (size > 0) {
		buff_dma_handle.val = (__u64) pci_map_single(h->pdev,
1855 1856
							     buff, size,
							     PCI_DMA_BIDIRECTIONAL);
L
Linus Torvalds 已提交
1857 1858 1859
		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
		c->SG[0].Len = size;
1860
		c->SG[0].Ext = 0;	/* we are not chaining */
L
Linus Torvalds 已提交
1861 1862 1863
	}
	return status;
}
1864 1865 1866 1867 1868 1869 1870

static int sendcmd_withirq(__u8 cmd,
			   int ctlr,
			   void *buff,
			   size_t size,
			   unsigned int use_unit_num,
			   unsigned int log_unit, __u8 page_code, int cmd_type)
L
Linus Torvalds 已提交
1871 1872 1873
{
	ctlr_info_t *h = hba[ctlr];
	CommandList_struct *c;
1874
	u64bit buff_dma_handle;
L
Linus Torvalds 已提交
1875 1876
	unsigned long flags;
	int return_status;
1877
	DECLARE_COMPLETION_ONSTACK(wait);
1878 1879

	if ((c = cmd_alloc(h, 0)) == NULL)
L
Linus Torvalds 已提交
1880 1881
		return -ENOMEM;
	return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
1882
				 log_unit, page_code, NULL, cmd_type);
L
Linus Torvalds 已提交
1883 1884 1885 1886
	if (return_status != IO_OK) {
		cmd_free(h, c, 0);
		return return_status;
	}
1887
      resend_cmd2:
L
Linus Torvalds 已提交
1888
	c->waiting = &wait;
1889

L
Linus Torvalds 已提交
1890 1891 1892 1893 1894 1895
	/* Put the request on the tail of the queue and send it */
	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
	addQ(&h->reqQ, c);
	h->Qdepth++;
	start_io(h);
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1896

L
Linus Torvalds 已提交
1897 1898
	wait_for_completion(&wait);

1899 1900 1901 1902 1903 1904 1905 1906 1907 1908
	if (c->err_info->CommandStatus != 0) {	/* an error has occurred */
		switch (c->err_info->CommandStatus) {
		case CMD_TARGET_STATUS:
			printk(KERN_WARNING "cciss: cmd %p has "
			       " completed with errors\n", c);
			if (c->err_info->ScsiStatus) {
				printk(KERN_WARNING "cciss: cmd %p "
				       "has SCSI Status = %x\n",
				       c, c->err_info->ScsiStatus);
			}
L
Linus Torvalds 已提交
1909 1910

			break;
1911 1912
		case CMD_DATA_UNDERRUN:
		case CMD_DATA_OVERRUN:
L
Linus Torvalds 已提交
1913 1914
			/* expected for inquire and report lun commands */
			break;
1915 1916 1917 1918
		case CMD_INVALID:
			printk(KERN_WARNING "cciss: Cmd %p is "
			       "reported invalid\n", c);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1919
			break;
1920 1921 1922 1923
		case CMD_PROTOCOL_ERR:
			printk(KERN_WARNING "cciss: cmd %p has "
			       "protocol error \n", c);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1924
			break;
1925 1926 1927 1928
		case CMD_HARDWARE_ERR:
			printk(KERN_WARNING "cciss: cmd %p had "
			       " hardware error\n", c);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1929
			break;
1930 1931 1932 1933
		case CMD_CONNECTION_LOST:
			printk(KERN_WARNING "cciss: cmd %p had "
			       "connection lost\n", c);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1934
			break;
1935 1936 1937 1938
		case CMD_ABORTED:
			printk(KERN_WARNING "cciss: cmd %p was "
			       "aborted\n", c);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1939
			break;
1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965
		case CMD_ABORT_FAILED:
			printk(KERN_WARNING "cciss: cmd %p reports "
			       "abort failed\n", c);
			return_status = IO_ERROR;
			break;
		case CMD_UNSOLICITED_ABORT:
			printk(KERN_WARNING
			       "cciss%d: unsolicited abort %p\n", ctlr, c);
			if (c->retry_count < MAX_CMD_RETRIES) {
				printk(KERN_WARNING
				       "cciss%d: retrying %p\n", ctlr, c);
				c->retry_count++;
				/* erase the old error information */
				memset(c->err_info, 0,
				       sizeof(ErrorInfo_struct));
				return_status = IO_OK;
				INIT_COMPLETION(wait);
				goto resend_cmd2;
			}
			return_status = IO_ERROR;
			break;
		default:
			printk(KERN_WARNING "cciss: cmd %p returned "
			       "unknown status %x\n", c,
			       c->err_info->CommandStatus);
			return_status = IO_ERROR;
L
Linus Torvalds 已提交
1966
		}
1967
	}
L
Linus Torvalds 已提交
1968
	/* unlock the buffers from DMA */
1969 1970
	buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
	buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
1971 1972
	pci_unmap_single(h->pdev, (dma_addr_t) buff_dma_handle.val,
			 c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
L
Linus Torvalds 已提交
1973
	cmd_free(h, c, 0);
1974
	return return_status;
L
Linus Torvalds 已提交
1975
}
1976

L
Linus Torvalds 已提交
1977
static void cciss_geometry_inquiry(int ctlr, int logvol,
1978
				   int withirq, sector_t total_size,
1979 1980 1981
				   unsigned int block_size,
				   InquiryData_struct *inq_buff,
				   drive_info_struct *drv)
L
Linus Torvalds 已提交
1982 1983
{
	int return_code;
1984 1985
	unsigned long t;

L
Linus Torvalds 已提交
1986 1987 1988
	memset(inq_buff, 0, sizeof(InquiryData_struct));
	if (withirq)
		return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
1989 1990
					      inq_buff, sizeof(*inq_buff), 1,
					      logvol, 0xC1, TYPE_CMD);
L
Linus Torvalds 已提交
1991 1992
	else
		return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
1993 1994
				      sizeof(*inq_buff), 1, logvol, 0xC1, NULL,
				      TYPE_CMD);
L
Linus Torvalds 已提交
1995
	if (return_code == IO_OK) {
1996
		if (inq_buff->data_byte[8] == 0xFF) {
L
Linus Torvalds 已提交
1997
			printk(KERN_WARNING
1998 1999
			       "cciss: reading geometry failed, volume "
			       "does not support reading geometry\n");
L
Linus Torvalds 已提交
2000
			drv->heads = 255;
2001
			drv->sectors = 32;	// Sectors per track
2002
			drv->cylinders = total_size + 1;
2003
			drv->raid_level = RAID_UNKNOWN;
L
Linus Torvalds 已提交
2004 2005 2006 2007 2008 2009
		} else {
			drv->heads = inq_buff->data_byte[6];
			drv->sectors = inq_buff->data_byte[7];
			drv->cylinders = (inq_buff->data_byte[4] & 0xff) << 8;
			drv->cylinders += inq_buff->data_byte[5];
			drv->raid_level = inq_buff->data_byte[8];
2010 2011
		}
		drv->block_size = block_size;
2012
		drv->nr_blocks = total_size + 1;
2013 2014
		t = drv->heads * drv->sectors;
		if (t > 1) {
2015 2016
			sector_t real_size = total_size + 1;
			unsigned long rem = sector_div(real_size, t);
2017
			if (rem)
2018 2019
				real_size++;
			drv->cylinders = real_size;
L
Linus Torvalds 已提交
2020
		}
2021
	} else {		/* Get geometry failed */
L
Linus Torvalds 已提交
2022 2023
		printk(KERN_WARNING "cciss: reading geometry failed\n");
	}
2024
	printk(KERN_INFO "      heads=%d, sectors=%d, cylinders=%d\n\n",
2025
	       drv->heads, drv->sectors, drv->cylinders);
L
Linus Torvalds 已提交
2026
}
2027

L
Linus Torvalds 已提交
2028
static void
2029
cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
2030
		    unsigned int *block_size)
L
Linus Torvalds 已提交
2031
{
2032
	ReadCapdata_struct *buf;
L
Linus Torvalds 已提交
2033
	int return_code;
2034 2035 2036

	buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
	if (!buf) {
2037 2038 2039
		printk(KERN_WARNING "cciss: out of memory\n");
		return;
	}
2040

L
Linus Torvalds 已提交
2041 2042
	if (withirq)
		return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
2043 2044
				ctlr, buf, sizeof(ReadCapdata_struct),
					1, logvol, 0, TYPE_CMD);
L
Linus Torvalds 已提交
2045 2046
	else
		return_code = sendcmd(CCISS_READ_CAPACITY,
2047 2048
				ctlr, buf, sizeof(ReadCapdata_struct),
					1, logvol, 0, NULL, TYPE_CMD);
L
Linus Torvalds 已提交
2049
	if (return_code == IO_OK) {
A
Al Viro 已提交
2050 2051
		*total_size = be32_to_cpu(*(__be32 *) buf->total_size);
		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
2052
	} else {		/* read capacity command failed */
L
Linus Torvalds 已提交
2053 2054 2055 2056
		printk(KERN_WARNING "cciss: read capacity failed\n");
		*total_size = 0;
		*block_size = BLOCK_SIZE;
	}
2057
	if (*total_size != 0)
2058
		printk(KERN_INFO "      blocks= %llu block_size= %d\n",
2059
		(unsigned long long)*total_size+1, *block_size);
2060 2061 2062 2063 2064 2065 2066 2067
	kfree(buf);
}

static void
cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, 				unsigned int *block_size)
{
	ReadCapdata_struct_16 *buf;
	int return_code;
2068 2069 2070

	buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
	if (!buf) {
2071 2072 2073
		printk(KERN_WARNING "cciss: out of memory\n");
		return;
	}
2074

2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085
	if (withirq) {
		return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
			ctlr, buf, sizeof(ReadCapdata_struct_16),
				1, logvol, 0, TYPE_CMD);
	}
	else {
		return_code = sendcmd(CCISS_READ_CAPACITY_16,
			ctlr, buf, sizeof(ReadCapdata_struct_16),
				1, logvol, 0, NULL, TYPE_CMD);
	}
	if (return_code == IO_OK) {
A
Al Viro 已提交
2086 2087
		*total_size = be64_to_cpu(*(__be64 *) buf->total_size);
		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
2088 2089 2090 2091 2092
	} else {		/* read capacity command failed */
		printk(KERN_WARNING "cciss: read capacity failed\n");
		*total_size = 0;
		*block_size = BLOCK_SIZE;
	}
2093
	printk(KERN_INFO "      blocks= %llu block_size= %d\n",
2094
	       (unsigned long long)*total_size+1, *block_size);
2095
	kfree(buf);
L
Linus Torvalds 已提交
2096 2097 2098 2099 2100 2101 2102
}

static int cciss_revalidate(struct gendisk *disk)
{
	ctlr_info_t *h = get_host(disk);
	drive_info_struct *drv = get_drv(disk);
	int logvol;
2103
	int FOUND = 0;
L
Linus Torvalds 已提交
2104
	unsigned int block_size;
2105
	sector_t total_size;
L
Linus Torvalds 已提交
2106 2107
	InquiryData_struct *inq_buff = NULL;

2108 2109 2110
	for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
		if (h->drv[logvol].LunID == drv->LunID) {
			FOUND = 1;
L
Linus Torvalds 已提交
2111 2112 2113 2114
			break;
		}
	}

2115 2116
	if (!FOUND)
		return 1;
L
Linus Torvalds 已提交
2117

2118 2119 2120 2121 2122
	inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
	if (inq_buff == NULL) {
		printk(KERN_WARNING "cciss: out of memory\n");
		return 1;
	}
2123 2124 2125 2126 2127 2128 2129
	if (h->cciss_read == CCISS_READ_10) {
		cciss_read_capacity(h->ctlr, logvol, 1,
					&total_size, &block_size);
	} else {
		cciss_read_capacity_16(h->ctlr, logvol, 1,
					&total_size, &block_size);
	}
2130 2131
	cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size,
			       inq_buff, drv);
L
Linus Torvalds 已提交
2132

M
Mike Miller 已提交
2133
	blk_queue_hardsect_size(drv->queue, drv->block_size);
L
Linus Torvalds 已提交
2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153
	set_capacity(disk, drv->nr_blocks);

	kfree(inq_buff);
	return 0;
}

/*
 *   Wait polling for a command to complete.
 *   The memory mapped FIFO is polled for the completion.
 *   Used only at init time, interrupts from the HBA are disabled.
 */
static unsigned long pollcomplete(int ctlr)
{
	unsigned long done;
	int i;

	/* Wait (up to 20 seconds) for a command to complete */

	for (i = 20 * HZ; i > 0; i--) {
		done = hba[ctlr]->access.command_completed(hba[ctlr]);
2154 2155 2156
		if (done == FIFO_EMPTY)
			schedule_timeout_uninterruptible(1);
		else
2157
			return done;
L
Linus Torvalds 已提交
2158 2159 2160 2161
	}
	/* Invalid address to tell caller we ran out of time */
	return 1;
}
2162 2163 2164 2165

static int add_sendcmd_reject(__u8 cmd, int ctlr, unsigned long complete)
{
	/* We get in here if sendcmd() is polling for completions
2166 2167 2168
	   and gets some command back that it wasn't expecting --
	   something other than that which it just sent down.
	   Ordinarily, that shouldn't happen, but it can happen when
2169
	   the scsi tape stuff gets into error handling mode, and
2170
	   starts using sendcmd() to try to abort commands and
2171 2172
	   reset tape drives.  In that case, sendcmd may pick up
	   completions of commands that were sent to logical drives
2173
	   through the block i/o system, or cciss ioctls completing, etc.
2174 2175
	   In that case, we need to save those completions for later
	   processing by the interrupt handler.
2176
	 */
2177 2178

#ifdef CONFIG_CISS_SCSI_TAPE
2179
	struct sendcmd_reject_list *srl = &hba[ctlr]->scsi_rejects;
2180 2181 2182 2183 2184

	/* If it's not the scsi tape stuff doing error handling, (abort */
	/* or reset) then we don't expect anything weird. */
	if (cmd != CCISS_RESET_MSG && cmd != CCISS_ABORT_MSG) {
#endif
2185 2186 2187
		printk(KERN_WARNING "cciss cciss%d: SendCmd "
		       "Invalid command list address returned! (%lx)\n",
		       ctlr, complete);
2188 2189 2190 2191 2192 2193 2194
		/* not much we can do. */
#ifdef CONFIG_CISS_SCSI_TAPE
		return 1;
	}

	/* We've sent down an abort or reset, but something else
	   has completed */
2195
	if (srl->ncompletions >= (hba[ctlr]->nr_cmds + 2)) {
2196 2197
		/* Uh oh.  No room to save it for later... */
		printk(KERN_WARNING "cciss%d: Sendcmd: Invalid command addr, "
2198
		       "reject list overflow, command lost!\n", ctlr);
2199 2200 2201 2202 2203 2204 2205 2206 2207
		return 1;
	}
	/* Save it for later */
	srl->complete[srl->ncompletions] = complete;
	srl->ncompletions++;
#endif
	return 0;
}

L
Linus Torvalds 已提交
2208
/*
2209 2210
 * Send a command to the controller, and wait for it to complete.
 * Only used at init time.
L
Linus Torvalds 已提交
2211
 */
2212 2213 2214 2215 2216
static int sendcmd(__u8 cmd, int ctlr, void *buff, size_t size, unsigned int use_unit_num,	/* 0: address the controller,
												   1: address logical volume log_unit,
												   2: periph device address is scsi3addr */
		   unsigned int log_unit,
		   __u8 page_code, unsigned char *scsi3addr, int cmd_type)
L
Linus Torvalds 已提交
2217 2218 2219 2220
{
	CommandList_struct *c;
	int i;
	unsigned long complete;
2221
	ctlr_info_t *info_p = hba[ctlr];
L
Linus Torvalds 已提交
2222
	u64bit buff_dma_handle;
2223
	int status, done = 0;
L
Linus Torvalds 已提交
2224 2225 2226

	if ((c = cmd_alloc(info_p, 1)) == NULL) {
		printk(KERN_WARNING "cciss: unable to get memory");
2227
		return IO_ERROR;
L
Linus Torvalds 已提交
2228 2229
	}
	status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
2230
			  log_unit, page_code, scsi3addr, cmd_type);
L
Linus Torvalds 已提交
2231 2232 2233 2234
	if (status != IO_OK) {
		cmd_free(info_p, c, 1);
		return status;
	}
2235
      resend_cmd1:
L
Linus Torvalds 已提交
2236
	/*
2237 2238
	 * Disable interrupt
	 */
L
Linus Torvalds 已提交
2239 2240
#ifdef CCISS_DEBUG
	printk(KERN_DEBUG "cciss: turning intr off\n");
2241 2242 2243
#endif				/* CCISS_DEBUG */
	info_p->access.set_intr_mask(info_p, CCISS_INTR_OFF);

L
Linus Torvalds 已提交
2244
	/* Make sure there is room in the command FIFO */
2245
	/* Actually it should be completely empty at this time */
2246 2247
	/* unless we are in here doing error handling for the scsi */
	/* tape side of the driver. */
2248
	for (i = 200000; i > 0; i--) {
L
Linus Torvalds 已提交
2249
		/* if fifo isn't full go */
2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
		if (!(info_p->access.fifo_full(info_p))) {

			break;
		}
		udelay(10);
		printk(KERN_WARNING "cciss cciss%d: SendCmd FIFO full,"
		       " waiting!\n", ctlr);
	}
	/*
	 * Send the cmd
	 */
	info_p->access.submit_command(info_p, c);
2262 2263 2264
	done = 0;
	do {
		complete = pollcomplete(ctlr);
L
Linus Torvalds 已提交
2265 2266

#ifdef CCISS_DEBUG
2267
		printk(KERN_DEBUG "cciss: command completed\n");
2268
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
2269

2270
		if (complete == 1) {
2271 2272 2273
			printk(KERN_WARNING
			       "cciss cciss%d: SendCmd Timeout out, "
			       "No command list address returned!\n", ctlr);
2274 2275 2276 2277 2278 2279
			status = IO_ERROR;
			done = 1;
			break;
		}

		/* This will need to change for direct lookup completions */
2280 2281 2282 2283 2284
		if ((complete & CISS_ERROR_BIT)
		    && (complete & ~CISS_ERROR_BIT) == c->busaddr) {
			/* if data overrun or underun on Report command
			   ignore it
			 */
L
Linus Torvalds 已提交
2285 2286 2287
			if (((c->Request.CDB[0] == CISS_REPORT_LOG) ||
			     (c->Request.CDB[0] == CISS_REPORT_PHYS) ||
			     (c->Request.CDB[0] == CISS_INQUIRY)) &&
2288 2289 2290 2291
			    ((c->err_info->CommandStatus ==
			      CMD_DATA_OVERRUN) ||
			     (c->err_info->CommandStatus == CMD_DATA_UNDERRUN)
			    )) {
L
Linus Torvalds 已提交
2292 2293 2294
				complete = c->busaddr;
			} else {
				if (c->err_info->CommandStatus ==
2295
				    CMD_UNSOLICITED_ABORT) {
L
Linus Torvalds 已提交
2296
					printk(KERN_WARNING "cciss%d: "
2297 2298
					       "unsolicited abort %p\n",
					       ctlr, c);
L
Linus Torvalds 已提交
2299 2300
					if (c->retry_count < MAX_CMD_RETRIES) {
						printk(KERN_WARNING
2301 2302
						       "cciss%d: retrying %p\n",
						       ctlr, c);
L
Linus Torvalds 已提交
2303 2304 2305 2306
						c->retry_count++;
						/* erase the old error */
						/* information */
						memset(c->err_info, 0,
2307 2308
						       sizeof
						       (ErrorInfo_struct));
L
Linus Torvalds 已提交
2309 2310 2311
						goto resend_cmd1;
					} else {
						printk(KERN_WARNING
2312 2313
						       "cciss%d: retried %p too "
						       "many times\n", ctlr, c);
L
Linus Torvalds 已提交
2314 2315 2316
						status = IO_ERROR;
						goto cleanup1;
					}
2317 2318 2319 2320 2321
				} else if (c->err_info->CommandStatus ==
					   CMD_UNABORTABLE) {
					printk(KERN_WARNING
					       "cciss%d: command could not be aborted.\n",
					       ctlr);
2322 2323
					status = IO_ERROR;
					goto cleanup1;
L
Linus Torvalds 已提交
2324 2325
				}
				printk(KERN_WARNING "ciss ciss%d: sendcmd"
2326 2327
				       " Error %x \n", ctlr,
				       c->err_info->CommandStatus);
L
Linus Torvalds 已提交
2328
				printk(KERN_WARNING "ciss ciss%d: sendcmd"
2329 2330 2331 2332 2333 2334 2335 2336 2337
				       " offensive info\n"
				       "  size %x\n   num %x   value %x\n",
				       ctlr,
				       c->err_info->MoreErrInfo.Invalid_Cmd.
				       offense_size,
				       c->err_info->MoreErrInfo.Invalid_Cmd.
				       offense_num,
				       c->err_info->MoreErrInfo.Invalid_Cmd.
				       offense_value);
L
Linus Torvalds 已提交
2338 2339 2340 2341
				status = IO_ERROR;
				goto cleanup1;
			}
		}
2342
		/* This will need changing for direct lookup completions */
2343
		if (complete != c->busaddr) {
2344
			if (add_sendcmd_reject(cmd, ctlr, complete) != 0) {
2345
				BUG();	/* we are pretty much hosed if we get here. */
2346 2347
			}
			continue;
2348
		} else
2349
			done = 1;
2350 2351 2352
	} while (!done);

      cleanup1:
L
Linus Torvalds 已提交
2353
	/* unlock the data buffer from DMA */
2354 2355
	buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
	buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
L
Linus Torvalds 已提交
2356
	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
2357
			 c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
2358 2359 2360
#ifdef CONFIG_CISS_SCSI_TAPE
	/* if we saved some commands for later, process them now. */
	if (info_p->scsi_rejects.ncompletions > 0)
2361
		do_cciss_intr(0, info_p);
2362
#endif
L
Linus Torvalds 已提交
2363
	cmd_free(info_p, c, 1);
2364
	return status;
2365 2366
}

L
Linus Torvalds 已提交
2367 2368 2369 2370 2371
/*
 * Map (physical) PCI mem into (virtual) kernel space
 */
static void __iomem *remap_pci_mem(ulong base, ulong size)
{
2372 2373 2374
	ulong page_base = ((ulong) base) & PAGE_MASK;
	ulong page_offs = ((ulong) base) - page_base;
	void __iomem *page_remapped = ioremap(page_base, page_offs + size);
L
Linus Torvalds 已提交
2375

2376
	return page_remapped ? (page_remapped + page_offs) : NULL;
L
Linus Torvalds 已提交
2377 2378
}

2379 2380 2381 2382 2383
/*
 * Takes jobs of the Q and sends them to the hardware, then puts it on
 * the Q to wait for completion.
 */
static void start_io(ctlr_info_t *h)
L
Linus Torvalds 已提交
2384 2385
{
	CommandList_struct *c;
2386 2387

	while ((c = h->reqQ) != NULL) {
L
Linus Torvalds 已提交
2388 2389 2390 2391 2392 2393
		/* can't do anything if fifo is full */
		if ((h->access.fifo_full(h))) {
			printk(KERN_WARNING "cciss: fifo full\n");
			break;
		}

2394
		/* Get the first entry from the Request Q */
L
Linus Torvalds 已提交
2395 2396
		removeQ(&(h->reqQ), c);
		h->Qdepth--;
2397 2398

		/* Tell the controller execute command */
L
Linus Torvalds 已提交
2399
		h->access.submit_command(h, c);
2400 2401 2402

		/* Put job onto the completed Q */
		addQ(&(h->cmpQ), c);
L
Linus Torvalds 已提交
2403 2404
	}
}
2405

L
Linus Torvalds 已提交
2406 2407 2408
/* Assumes that CCISS_LOCK(h->ctlr) is held. */
/* Zeros out the error record and then resends the command back */
/* to the controller */
2409
static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
L
Linus Torvalds 已提交
2410 2411 2412 2413 2414
{
	/* erase the old error information */
	memset(c->err_info, 0, sizeof(ErrorInfo_struct));

	/* add it to software queue and then send it to the controller */
2415
	addQ(&(h->reqQ), c);
L
Linus Torvalds 已提交
2416
	h->Qdepth++;
2417
	if (h->Qdepth > h->maxQsinceinit)
L
Linus Torvalds 已提交
2418 2419 2420 2421
		h->maxQsinceinit = h->Qdepth;

	start_io(h);
}
2422

2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
static inline unsigned int make_status_bytes(unsigned int scsi_status_byte,
	unsigned int msg_byte, unsigned int host_byte,
	unsigned int driver_byte)
{
	/* inverse of macros in scsi.h */
	return (scsi_status_byte & 0xff) |
		((msg_byte & 0xff) << 8) |
		((host_byte & 0xff) << 16) |
		((driver_byte & 0xff) << 24);
}

2434 2435 2436
static inline int evaluate_target_status(CommandList_struct *cmd)
{
	unsigned char sense_key;
2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451
	unsigned char status_byte, msg_byte, host_byte, driver_byte;
	int error_value;

	/* If we get in here, it means we got "target status", that is, scsi status */
	status_byte = cmd->err_info->ScsiStatus;
	driver_byte = DRIVER_OK;
	msg_byte = cmd->err_info->CommandStatus; /* correct?  seems too device specific */

	if (blk_pc_request(cmd->rq))
		host_byte = DID_PASSTHROUGH;
	else
		host_byte = DID_OK;

	error_value = make_status_bytes(status_byte, msg_byte,
		host_byte, driver_byte);
2452

2453
	if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) {
2454 2455 2456 2457
		if (!blk_pc_request(cmd->rq))
			printk(KERN_WARNING "cciss: cmd %p "
			       "has SCSI Status 0x%x\n",
			       cmd, cmd->err_info->ScsiStatus);
2458
		return error_value;
2459 2460 2461 2462 2463
	}

	/* check the sense key */
	sense_key = 0xf & cmd->err_info->SenseInfo[2];
	/* no status or recovered error */
2464 2465
	if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq))
		error_value = 0;
2466 2467

	if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
2468
		if (error_value != 0)
2469 2470
			printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
			       " sense key = 0x%x\n", cmd, sense_key);
2471
		return error_value;
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482
	}

	/* SG_IO or similar, copy sense data back */
	if (cmd->rq->sense) {
		if (cmd->rq->sense_len > cmd->err_info->SenseLen)
			cmd->rq->sense_len = cmd->err_info->SenseLen;
		memcpy(cmd->rq->sense, cmd->err_info->SenseInfo,
			cmd->rq->sense_len);
	} else
		cmd->rq->sense_len = 0;

2483
	return error_value;
2484 2485
}

2486
/* checks the status of the job and calls complete buffers to mark all
2487 2488
 * buffers for the completed job. Note that this function does not need
 * to hold the hba/queue lock.
2489 2490 2491
 */
static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
				    int timeout)
L
Linus Torvalds 已提交
2492 2493
{
	int retry_cmd = 0;
2494 2495 2496
	struct request *rq = cmd->rq;

	rq->errors = 0;
2497

L
Linus Torvalds 已提交
2498
	if (timeout)
2499
		rq->errors = make_status_bytes(0, 0, 0, DRIVER_TIMEOUT);
L
Linus Torvalds 已提交
2500

2501 2502
	if (cmd->err_info->CommandStatus == 0)	/* no error has occurred */
		goto after_error_processing;
2503

2504 2505
	switch (cmd->err_info->CommandStatus) {
	case CMD_TARGET_STATUS:
2506
		rq->errors = evaluate_target_status(cmd);
2507 2508
		break;
	case CMD_DATA_UNDERRUN:
2509 2510 2511 2512 2513 2514
		if (blk_fs_request(cmd->rq)) {
			printk(KERN_WARNING "cciss: cmd %p has"
			       " completed with data underrun "
			       "reported\n", cmd);
			cmd->rq->data_len = cmd->err_info->ResidualCnt;
		}
2515 2516
		break;
	case CMD_DATA_OVERRUN:
2517 2518 2519 2520
		if (blk_fs_request(cmd->rq))
			printk(KERN_WARNING "cciss: cmd %p has"
			       " completed with data overrun "
			       "reported\n", cmd);
2521 2522 2523 2524
		break;
	case CMD_INVALID:
		printk(KERN_WARNING "cciss: cmd %p is "
		       "reported invalid\n", cmd);
2525 2526 2527
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2528 2529 2530 2531
		break;
	case CMD_PROTOCOL_ERR:
		printk(KERN_WARNING "cciss: cmd %p has "
		       "protocol error \n", cmd);
2532 2533 2534
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2535 2536 2537 2538
		break;
	case CMD_HARDWARE_ERR:
		printk(KERN_WARNING "cciss: cmd %p had "
		       " hardware error\n", cmd);
2539 2540 2541
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2542 2543 2544 2545
		break;
	case CMD_CONNECTION_LOST:
		printk(KERN_WARNING "cciss: cmd %p had "
		       "connection lost\n", cmd);
2546 2547 2548
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2549 2550 2551 2552
		break;
	case CMD_ABORTED:
		printk(KERN_WARNING "cciss: cmd %p was "
		       "aborted\n", cmd);
2553 2554 2555
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT);
2556 2557 2558 2559
		break;
	case CMD_ABORT_FAILED:
		printk(KERN_WARNING "cciss: cmd %p reports "
		       "abort failed\n", cmd);
2560 2561 2562
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575
		break;
	case CMD_UNSOLICITED_ABORT:
		printk(KERN_WARNING "cciss%d: unsolicited "
		       "abort %p\n", h->ctlr, cmd);
		if (cmd->retry_count < MAX_CMD_RETRIES) {
			retry_cmd = 1;
			printk(KERN_WARNING
			       "cciss%d: retrying %p\n", h->ctlr, cmd);
			cmd->retry_count++;
		} else
			printk(KERN_WARNING
			       "cciss%d: %p retried too "
			       "many times\n", h->ctlr, cmd);
2576 2577 2578
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT);
2579 2580 2581
		break;
	case CMD_TIMEOUT:
		printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
2582 2583 2584
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
2585 2586 2587 2588 2589
		break;
	default:
		printk(KERN_WARNING "cciss: cmd %p returned "
		       "unknown status %x\n", cmd,
		       cmd->err_info->CommandStatus);
2590 2591 2592
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
L
Linus Torvalds 已提交
2593
	}
2594 2595 2596

after_error_processing:

L
Linus Torvalds 已提交
2597
	/* We need to return this command */
2598 2599
	if (retry_cmd) {
		resend_cciss_cmd(h, cmd);
L
Linus Torvalds 已提交
2600
		return;
2601
	}
2602
	cmd->rq->completion_data = cmd;
2603
	blk_complete_request(cmd->rq);
L
Linus Torvalds 已提交
2604 2605
}

2606 2607
/*
 * Get a request and submit it to the controller.
L
Linus Torvalds 已提交
2608
 */
2609
static void do_cciss_request(struct request_queue *q)
L
Linus Torvalds 已提交
2610
{
2611
	ctlr_info_t *h = q->queuedata;
L
Linus Torvalds 已提交
2612
	CommandList_struct *c;
2613 2614
	sector_t start_blk;
	int seg;
L
Linus Torvalds 已提交
2615 2616 2617 2618 2619 2620 2621 2622
	struct request *creq;
	u64bit temp64;
	struct scatterlist tmp_sg[MAXSGENTRIES];
	drive_info_struct *drv;
	int i, dir;

	/* We call start_io here in case there is a command waiting on the
	 * queue that has not been sent.
2623
	 */
L
Linus Torvalds 已提交
2624 2625 2626
	if (blk_queue_plugged(q))
		goto startio;

2627
      queue:
L
Linus Torvalds 已提交
2628 2629 2630 2631
	creq = elv_next_request(q);
	if (!creq)
		goto startio;

2632
	BUG_ON(creq->nr_phys_segments > MAXSGENTRIES);
L
Linus Torvalds 已提交
2633

2634
	if ((c = cmd_alloc(h, 1)) == NULL)
L
Linus Torvalds 已提交
2635 2636 2637 2638 2639 2640 2641 2642
		goto full;

	blkdev_dequeue_request(creq);

	spin_unlock_irq(q->queue_lock);

	c->cmd_type = CMD_RWREQ;
	c->rq = creq;
2643 2644

	/* fill in the request */
L
Linus Torvalds 已提交
2645
	drv = creq->rq_disk->private_data;
2646
	c->Header.ReplyQueue = 0;	// unused in simple mode
2647 2648 2649 2650
	/* got command from pool, so use the command block index instead */
	/* for direct lookups. */
	/* The first 2 bits are reserved for controller error reporting. */
	c->Header.Tag.lower = (c->cmdindex << 3);
2651 2652
	c->Header.Tag.lower |= 0x04;	/* flag for direct lookup. */
	c->Header.LUN.LogDev.VolId = drv->LunID;
L
Linus Torvalds 已提交
2653
	c->Header.LUN.LogDev.Mode = 1;
2654 2655 2656 2657
	c->Request.CDBLen = 10;	// 12 byte commands not in FW yet;
	c->Request.Type.Type = TYPE_CMD;	// It is a command.
	c->Request.Type.Attribute = ATTR_SIMPLE;
	c->Request.Type.Direction =
2658
	    (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE;
2659 2660
	c->Request.Timeout = 0;	// Don't time out
	c->Request.CDB[0] =
2661
	    (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write;
L
Linus Torvalds 已提交
2662 2663
	start_blk = creq->sector;
#ifdef CCISS_DEBUG
2664 2665 2666
	printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector,
	       (int)creq->nr_sectors);
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
2667

J
Jens Axboe 已提交
2668
	sg_init_table(tmp_sg, MAXSGENTRIES);
L
Linus Torvalds 已提交
2669 2670
	seg = blk_rq_map_sg(q, creq, tmp_sg);

2671
	/* get the DMA records for the setup */
L
Linus Torvalds 已提交
2672 2673 2674 2675 2676
	if (c->Request.Type.Direction == XFER_READ)
		dir = PCI_DMA_FROMDEVICE;
	else
		dir = PCI_DMA_TODEVICE;

2677
	for (i = 0; i < seg; i++) {
L
Linus Torvalds 已提交
2678
		c->SG[i].Len = tmp_sg[i].length;
J
Jens Axboe 已提交
2679
		temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
2680 2681
						  tmp_sg[i].offset,
						  tmp_sg[i].length, dir);
L
Linus Torvalds 已提交
2682
		c->SG[i].Addr.lower = temp64.val32.lower;
2683 2684
		c->SG[i].Addr.upper = temp64.val32.upper;
		c->SG[i].Ext = 0;	// we are not chaining
L
Linus Torvalds 已提交
2685
	}
2686 2687 2688
	/* track how many SG entries we are using */
	if (seg > h->maxSG)
		h->maxSG = seg;
L
Linus Torvalds 已提交
2689 2690

#ifdef CCISS_DEBUG
2691 2692 2693
	printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n",
	       creq->nr_sectors, seg);
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
2694 2695

	c->Header.SGList = c->Header.SGTotal = seg;
2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707
	if (likely(blk_fs_request(creq))) {
		if(h->cciss_read == CCISS_READ_10) {
			c->Request.CDB[1] = 0;
			c->Request.CDB[2] = (start_blk >> 24) & 0xff;	//MSB
			c->Request.CDB[3] = (start_blk >> 16) & 0xff;
			c->Request.CDB[4] = (start_blk >> 8) & 0xff;
			c->Request.CDB[5] = start_blk & 0xff;
			c->Request.CDB[6] = 0;	// (sect >> 24) & 0xff; MSB
			c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
			c->Request.CDB[8] = creq->nr_sectors & 0xff;
			c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
		} else {
2708 2709
			u32 upper32 = upper_32_bits(start_blk);

2710 2711
			c->Request.CDBLen = 16;
			c->Request.CDB[1]= 0;
2712 2713 2714 2715
			c->Request.CDB[2]= (upper32 >> 24) & 0xff;	//MSB
			c->Request.CDB[3]= (upper32 >> 16) & 0xff;
			c->Request.CDB[4]= (upper32 >>  8) & 0xff;
			c->Request.CDB[5]= upper32 & 0xff;
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728
			c->Request.CDB[6]= (start_blk >> 24) & 0xff;
			c->Request.CDB[7]= (start_blk >> 16) & 0xff;
			c->Request.CDB[8]= (start_blk >>  8) & 0xff;
			c->Request.CDB[9]= start_blk & 0xff;
			c->Request.CDB[10]= (creq->nr_sectors >>  24) & 0xff;
			c->Request.CDB[11]= (creq->nr_sectors >>  16) & 0xff;
			c->Request.CDB[12]= (creq->nr_sectors >>  8) & 0xff;
			c->Request.CDB[13]= creq->nr_sectors & 0xff;
			c->Request.CDB[14] = c->Request.CDB[15] = 0;
		}
	} else if (blk_pc_request(creq)) {
		c->Request.CDBLen = creq->cmd_len;
		memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
2729
	} else {
2730 2731
		printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type);
		BUG();
2732
	}
L
Linus Torvalds 已提交
2733 2734 2735

	spin_lock_irq(q->queue_lock);

2736
	addQ(&(h->reqQ), c);
L
Linus Torvalds 已提交
2737
	h->Qdepth++;
2738 2739
	if (h->Qdepth > h->maxQsinceinit)
		h->maxQsinceinit = h->Qdepth;
L
Linus Torvalds 已提交
2740 2741

	goto queue;
2742
full:
L
Linus Torvalds 已提交
2743
	blk_stop_queue(q);
2744
startio:
L
Linus Torvalds 已提交
2745 2746
	/* We will already have the driver lock here so not need
	 * to lock it.
2747
	 */
L
Linus Torvalds 已提交
2748 2749 2750
	start_io(h);
}

2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773
static inline unsigned long get_next_completion(ctlr_info_t *h)
{
#ifdef CONFIG_CISS_SCSI_TAPE
	/* Any rejects from sendcmd() lying around? Process them first */
	if (h->scsi_rejects.ncompletions == 0)
		return h->access.command_completed(h);
	else {
		struct sendcmd_reject_list *srl;
		int n;
		srl = &h->scsi_rejects;
		n = --srl->ncompletions;
		/* printk("cciss%d: processing saved reject\n", h->ctlr); */
		printk("p");
		return srl->complete[n];
	}
#else
	return h->access.command_completed(h);
#endif
}

static inline int interrupt_pending(ctlr_info_t *h)
{
#ifdef CONFIG_CISS_SCSI_TAPE
2774
	return (h->access.intr_pending(h)
2775 2776 2777 2778 2779 2780 2781 2782 2783
		|| (h->scsi_rejects.ncompletions > 0));
#else
	return h->access.intr_pending(h);
#endif
}

static inline long interrupt_not_for_us(ctlr_info_t *h)
{
#ifdef CONFIG_CISS_SCSI_TAPE
2784 2785 2786
	return (((h->access.intr_pending(h) == 0) ||
		 (h->interrupts_enabled == 0))
		&& (h->scsi_rejects.ncompletions == 0));
2787
#else
2788
	return (((h->access.intr_pending(h) == 0) ||
2789 2790 2791 2792
		 (h->interrupts_enabled == 0)));
#endif
}

2793
static irqreturn_t do_cciss_intr(int irq, void *dev_id)
L
Linus Torvalds 已提交
2794 2795 2796 2797
{
	ctlr_info_t *h = dev_id;
	CommandList_struct *c;
	unsigned long flags;
2798
	__u32 a, a1, a2;
L
Linus Torvalds 已提交
2799

2800
	if (interrupt_not_for_us(h))
L
Linus Torvalds 已提交
2801 2802 2803 2804 2805 2806
		return IRQ_NONE;
	/*
	 * If there are completed commands in the completion queue,
	 * we had better do something about it.
	 */
	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
2807
	while (interrupt_pending(h)) {
2808
		while ((a = get_next_completion(h)) != FIFO_EMPTY) {
L
Linus Torvalds 已提交
2809
			a1 = a;
2810 2811
			if ((a & 0x04)) {
				a2 = (a >> 3);
2812
				if (a2 >= h->nr_cmds) {
2813 2814 2815
					printk(KERN_WARNING
					       "cciss: controller cciss%d failed, stopping.\n",
					       h->ctlr);
2816 2817 2818 2819 2820 2821 2822 2823
					fail_all_cmds(h->ctlr);
					return IRQ_HANDLED;
				}

				c = h->cmd_pool + a2;
				a = c->busaddr;

			} else {
2824
				a &= ~3;
2825
				if ((c = h->cmpQ) == NULL) {
2826 2827 2828 2829 2830 2831 2832 2833 2834 2835
					printk(KERN_WARNING
					       "cciss: Completion of %08x ignored\n",
					       a1);
					continue;
				}
				while (c->busaddr != a) {
					c = c->next;
					if (c == h->cmpQ)
						break;
				}
2836
			}
L
Linus Torvalds 已提交
2837 2838 2839 2840
			/*
			 * If we've found the command, take it off the
			 * completion Q and free it
			 */
2841
			if (c->busaddr == a) {
L
Linus Torvalds 已提交
2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859
				removeQ(&h->cmpQ, c);
				if (c->cmd_type == CMD_RWREQ) {
					complete_command(h, c, 0);
				} else if (c->cmd_type == CMD_IOCTL_PEND) {
					complete(c->waiting);
				}
#				ifdef CONFIG_CISS_SCSI_TAPE
				else if (c->cmd_type == CMD_SCSI)
					complete_scsi_command(c, 0, a1);
#				endif
				continue;
			}
		}
	}

	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
	return IRQ_HANDLED;
}
2860 2861

/*
2862
 *  We cannot read the structure directly, for portability we must use
L
Linus Torvalds 已提交
2863
 *   the io functions.
2864
 *   This is for debug only.
L
Linus Torvalds 已提交
2865 2866
 */
#ifdef CCISS_DEBUG
2867
static void print_cfg_table(CfgTable_struct *tb)
L
Linus Torvalds 已提交
2868 2869 2870 2871 2872 2873
{
	int i;
	char temp_name[17];

	printk("Controller Configuration information\n");
	printk("------------------------------------\n");
2874
	for (i = 0; i < 4; i++)
L
Linus Torvalds 已提交
2875
		temp_name[i] = readb(&(tb->Signature[i]));
2876 2877
	temp_name[4] = '\0';
	printk("   Signature = %s\n", temp_name);
L
Linus Torvalds 已提交
2878
	printk("   Spec Number = %d\n", readl(&(tb->SpecValence)));
2879 2880 2881 2882 2883 2884
	printk("   Transport methods supported = 0x%x\n",
	       readl(&(tb->TransportSupport)));
	printk("   Transport methods active = 0x%x\n",
	       readl(&(tb->TransportActive)));
	printk("   Requested transport Method = 0x%x\n",
	       readl(&(tb->HostWrite.TransportRequest)));
2885
	printk("   Coalesce Interrupt Delay = 0x%x\n",
2886
	       readl(&(tb->HostWrite.CoalIntDelay)));
2887
	printk("   Coalesce Interrupt Count = 0x%x\n",
2888 2889 2890 2891 2892
	       readl(&(tb->HostWrite.CoalIntCount)));
	printk("   Max outstanding commands = 0x%d\n",
	       readl(&(tb->CmdsOutMax)));
	printk("   Bus Types = 0x%x\n", readl(&(tb->BusTypes)));
	for (i = 0; i < 16; i++)
L
Linus Torvalds 已提交
2893 2894 2895
		temp_name[i] = readb(&(tb->ServerName[i]));
	temp_name[16] = '\0';
	printk("   Server Name = %s\n", temp_name);
2896
	printk("   Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat)));
L
Linus Torvalds 已提交
2897
}
2898
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
2899

2900
static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr)
L
Linus Torvalds 已提交
2901 2902
{
	int i, offset, mem_type, bar_type;
2903
	if (pci_bar_addr == PCI_BASE_ADDRESS_0)	/* looking for BAR zero? */
L
Linus Torvalds 已提交
2904 2905
		return 0;
	offset = 0;
2906 2907
	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
		bar_type = pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE;
L
Linus Torvalds 已提交
2908 2909 2910 2911
		if (bar_type == PCI_BASE_ADDRESS_SPACE_IO)
			offset += 4;
		else {
			mem_type = pci_resource_flags(pdev, i) &
2912
			    PCI_BASE_ADDRESS_MEM_TYPE_MASK;
L
Linus Torvalds 已提交
2913
			switch (mem_type) {
2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924
			case PCI_BASE_ADDRESS_MEM_TYPE_32:
			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
				offset += 4;	/* 32 bit */
				break;
			case PCI_BASE_ADDRESS_MEM_TYPE_64:
				offset += 8;
				break;
			default:	/* reserved in PCI 2.2 */
				printk(KERN_WARNING
				       "Base address is invalid\n");
				return -1;
L
Linus Torvalds 已提交
2925 2926 2927
				break;
			}
		}
2928 2929
		if (offset == pci_bar_addr - PCI_BASE_ADDRESS_0)
			return i + 1;
L
Linus Torvalds 已提交
2930 2931 2932 2933
	}
	return -1;
}

2934 2935 2936 2937
/* If MSI/MSI-X is supported by the kernel we will try to enable it on
 * controllers that are capable. If not, we use IO-APIC mode.
 */

2938 2939
static void __devinit cciss_interrupt_mode(ctlr_info_t *c,
					   struct pci_dev *pdev, __u32 board_id)
2940 2941
{
#ifdef CONFIG_PCI_MSI
2942 2943 2944 2945
	int err;
	struct msix_entry cciss_msix_entries[4] = { {0, 0}, {0, 1},
	{0, 2}, {0, 3}
	};
2946 2947 2948

	/* Some boards advertise MSI but don't really support it */
	if ((board_id == 0x40700E11) ||
2949 2950
	    (board_id == 0x40800E11) ||
	    (board_id == 0x40820E11) || (board_id == 0x40830E11))
2951 2952
		goto default_int_mode;

2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965
	if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
		err = pci_enable_msix(pdev, cciss_msix_entries, 4);
		if (!err) {
			c->intr[0] = cciss_msix_entries[0].vector;
			c->intr[1] = cciss_msix_entries[1].vector;
			c->intr[2] = cciss_msix_entries[2].vector;
			c->intr[3] = cciss_msix_entries[3].vector;
			c->msix_vector = 1;
			return;
		}
		if (err > 0) {
			printk(KERN_WARNING "cciss: only %d MSI-X vectors "
			       "available\n", err);
2966
			goto default_int_mode;
2967 2968 2969
		} else {
			printk(KERN_WARNING "cciss: MSI-X init failed %d\n",
			       err);
2970
			goto default_int_mode;
2971 2972 2973 2974 2975 2976 2977 2978 2979
		}
	}
	if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
		if (!pci_enable_msi(pdev)) {
			c->msi_vector = 1;
		} else {
			printk(KERN_WARNING "cciss: MSI init failed\n");
		}
	}
2980
default_int_mode:
2981
#endif				/* CONFIG_PCI_MSI */
2982
	/* if we get here we're going to use the default interrupt mode */
2983
	c->intr[SIMPLE_MODE_INT] = pdev->irq;
2984 2985 2986
	return;
}

R
Randy Dunlap 已提交
2987
static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
L
Linus Torvalds 已提交
2988 2989 2990 2991 2992 2993
{
	ushort subsystem_vendor_id, subsystem_device_id, command;
	__u32 board_id, scratchpad = 0;
	__u64 cfg_offset;
	__u32 cfg_base_addr;
	__u64 cfg_base_addr_index;
2994
	int i, err;
L
Linus Torvalds 已提交
2995 2996 2997

	/* check to see if controller has been disabled */
	/* BEFORE trying to enable it */
2998 2999 3000 3001
	(void)pci_read_config_word(pdev, PCI_COMMAND, &command);
	if (!(command & 0x02)) {
		printk(KERN_WARNING
		       "cciss: controller appears to be disabled\n");
3002
		return -ENODEV;
L
Linus Torvalds 已提交
3003 3004
	}

3005
	err = pci_enable_device(pdev);
3006
	if (err) {
L
Linus Torvalds 已提交
3007
		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
3008
		return err;
L
Linus Torvalds 已提交
3009 3010
	}

3011 3012 3013
	err = pci_request_regions(pdev, "cciss");
	if (err) {
		printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
3014
		       "aborting\n");
3015
		return err;
3016 3017
	}

L
Linus Torvalds 已提交
3018 3019 3020
	subsystem_vendor_id = pdev->subsystem_vendor;
	subsystem_device_id = pdev->subsystem_device;
	board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
3021
		    subsystem_vendor_id);
L
Linus Torvalds 已提交
3022 3023 3024 3025 3026

#ifdef CCISS_DEBUG
	printk("command = %x\n", command);
	printk("irq = %x\n", pdev->irq);
	printk("board_id = %x\n", board_id);
3027
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3028

3029 3030 3031 3032
/* If the kernel supports MSI/MSI-X we will try to enable that functionality,
 * else we use the IO-APIC interrupt assigned to us by system ROM.
 */
	cciss_interrupt_mode(c, pdev, board_id);
L
Linus Torvalds 已提交
3033 3034 3035

	/*
	 * Memory base addr is first addr , the second points to the config
3036
	 *   table
L
Linus Torvalds 已提交
3037 3038
	 */

3039
	c->paddr = pci_resource_start(pdev, 0);	/* addressing mode bits already removed */
L
Linus Torvalds 已提交
3040 3041
#ifdef CCISS_DEBUG
	printk("address 0 = %x\n", c->paddr);
3042
#endif				/* CCISS_DEBUG */
3043
	c->vaddr = remap_pci_mem(c->paddr, 0x250);
L
Linus Torvalds 已提交
3044 3045 3046

	/* Wait for the board to become ready.  (PCI hotplug needs this.)
	 * We poll for up to 120 secs, once per 100ms. */
3047
	for (i = 0; i < 1200; i++) {
L
Linus Torvalds 已提交
3048 3049 3050 3051
		scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET);
		if (scratchpad == CCISS_FIRMWARE_READY)
			break;
		set_current_state(TASK_INTERRUPTIBLE);
3052
		schedule_timeout(HZ / 10);	/* wait 100ms */
L
Linus Torvalds 已提交
3053 3054 3055
	}
	if (scratchpad != CCISS_FIRMWARE_READY) {
		printk(KERN_WARNING "cciss: Board not ready.  Timed out.\n");
3056
		err = -ENODEV;
3057
		goto err_out_free_res;
L
Linus Torvalds 已提交
3058 3059 3060 3061 3062 3063 3064
	}

	/* get the address index number */
	cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET);
	cfg_base_addr &= (__u32) 0x0000ffff;
#ifdef CCISS_DEBUG
	printk("cfg base address = %x\n", cfg_base_addr);
3065 3066
#endif				/* CCISS_DEBUG */
	cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr);
L
Linus Torvalds 已提交
3067 3068
#ifdef CCISS_DEBUG
	printk("cfg base address index = %x\n", cfg_base_addr_index);
3069
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3070 3071
	if (cfg_base_addr_index == -1) {
		printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
3072
		err = -ENODEV;
3073
		goto err_out_free_res;
L
Linus Torvalds 已提交
3074 3075 3076 3077 3078
	}

	cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);
#ifdef CCISS_DEBUG
	printk("cfg offset = %x\n", cfg_offset);
3079 3080 3081 3082
#endif				/* CCISS_DEBUG */
	c->cfgtable = remap_pci_mem(pci_resource_start(pdev,
						       cfg_base_addr_index) +
				    cfg_offset, sizeof(CfgTable_struct));
L
Linus Torvalds 已提交
3083 3084 3085
	c->board_id = board_id;

#ifdef CCISS_DEBUG
3086
	print_cfg_table(c->cfgtable);
3087
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3088

3089
	for (i = 0; i < ARRAY_SIZE(products); i++) {
L
Linus Torvalds 已提交
3090 3091 3092
		if (board_id == products[i].board_id) {
			c->product_name = products[i].product_name;
			c->access = *(products[i].access);
3093
			c->nr_cmds = products[i].nr_cmds;
L
Linus Torvalds 已提交
3094 3095 3096
			break;
		}
	}
3097 3098 3099 3100
	if ((readb(&c->cfgtable->Signature[0]) != 'C') ||
	    (readb(&c->cfgtable->Signature[1]) != 'I') ||
	    (readb(&c->cfgtable->Signature[2]) != 'S') ||
	    (readb(&c->cfgtable->Signature[3]) != 'S')) {
L
Linus Torvalds 已提交
3101
		printk("Does not appear to be a valid CISS config table\n");
3102
		err = -ENODEV;
3103
		goto err_out_free_res;
L
Linus Torvalds 已提交
3104
	}
3105 3106 3107 3108 3109 3110 3111 3112
	/* We didn't find the controller in our list. We know the
	 * signature is valid. If it's an HP device let's try to
	 * bind to the device and fire it up. Otherwise we bail.
	 */
	if (i == ARRAY_SIZE(products)) {
		if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
			c->product_name = products[i-1].product_name;
			c->access = *(products[i-1].access);
3113
			c->nr_cmds = products[i-1].nr_cmds;
3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125
			printk(KERN_WARNING "cciss: This is an unknown "
				"Smart Array controller.\n"
				"cciss: Please update to the latest driver "
				"available from www.hp.com.\n");
		} else {
			printk(KERN_WARNING "cciss: Sorry, I don't know how"
				" to access the Smart Array controller %08lx\n"
					, (unsigned long)board_id);
			err = -ENODEV;
			goto err_out_free_res;
		}
	}
L
Linus Torvalds 已提交
3126
#ifdef CONFIG_X86
3127 3128 3129 3130 3131 3132 3133
	{
		/* Need to enable prefetch in the SCSI core for 6400 in x86 */
		__u32 prefetch;
		prefetch = readl(&(c->cfgtable->SCSI_Prefetch));
		prefetch |= 0x100;
		writel(prefetch, &(c->cfgtable->SCSI_Prefetch));
	}
L
Linus Torvalds 已提交
3134 3135
#endif

3136 3137 3138 3139
	/* Disabling DMA prefetch and refetch for the P600.
	 * An ASIC bug may result in accesses to invalid memory addresses.
	 * We've disabled prefetch for some time now. Testing with XEN
	 * kernels revealed a bug in the refetch if dom0 resides on a P600.
3140 3141 3142
	 */
	if(board_id == 0x3225103C) {
		__u32 dma_prefetch;
3143
		__u32 dma_refetch;
3144 3145 3146
		dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG);
		dma_prefetch |= 0x8000;
		writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG);
3147 3148 3149
		pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch);
		dma_refetch |= 0x1;
		pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch);
3150 3151
	}

L
Linus Torvalds 已提交
3152 3153
#ifdef CCISS_DEBUG
	printk("Trying to put board into Simple mode\n");
3154
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3155
	c->max_commands = readl(&(c->cfgtable->CmdsOutMax));
3156 3157 3158
	/* Update the field, and then ring the doorbell */
	writel(CFGTBL_Trans_Simple, &(c->cfgtable->HostWrite.TransportRequest));
	writel(CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
L
Linus Torvalds 已提交
3159 3160 3161 3162

	/* under certain very rare conditions, this can take awhile.
	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
	 * as we enter this code.) */
3163
	for (i = 0; i < MAX_CONFIG_WAIT; i++) {
L
Linus Torvalds 已提交
3164 3165 3166 3167 3168
		if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
			break;
		/* delay and try again */
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(10);
3169
	}
L
Linus Torvalds 已提交
3170 3171

#ifdef CCISS_DEBUG
3172 3173 3174
	printk(KERN_DEBUG "I counter got to %d %x\n", i,
	       readl(c->vaddr + SA5_DOORBELL));
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3175
#ifdef CCISS_DEBUG
3176 3177
	print_cfg_table(c->cfgtable);
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3178

3179
	if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) {
L
Linus Torvalds 已提交
3180
		printk(KERN_WARNING "cciss: unable to get board into"
3181
		       " simple mode\n");
3182
		err = -ENODEV;
3183
		goto err_out_free_res;
L
Linus Torvalds 已提交
3184 3185 3186
	}
	return 0;

3187
err_out_free_res:
3188 3189 3190 3191
	/*
	 * Deliberately omit pci_disable_device(): it does something nasty to
	 * Smart Array controllers that pci_enable_device does not undo
	 */
3192
	pci_release_regions(pdev);
3193
	return err;
L
Linus Torvalds 已提交
3194 3195
}

3196 3197 3198
/*
 * Gets information about the local volumes attached to the controller.
 */
L
Linus Torvalds 已提交
3199 3200 3201 3202 3203 3204 3205 3206
static void cciss_getgeometry(int cntl_num)
{
	ReportLunData_struct *ld_buff;
	InquiryData_struct *inq_buff;
	int return_code;
	int i;
	int listlength = 0;
	__u32 lunid = 0;
A
Al Viro 已提交
3207
	unsigned block_size;
3208
	sector_t total_size;
L
Linus Torvalds 已提交
3209

3210
	ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
3211 3212 3213 3214 3215 3216 3217
	if (ld_buff == NULL) {
		printk(KERN_ERR "cciss: out of memory\n");
		return;
	}
	inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
	if (inq_buff == NULL) {
		printk(KERN_ERR "cciss: out of memory\n");
L
Linus Torvalds 已提交
3218
		kfree(ld_buff);
3219 3220 3221 3222 3223 3224 3225
		return;
	}
	/* Get the firmware version */
	return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
			      sizeof(InquiryData_struct), 0, 0, 0, NULL,
			      TYPE_CMD);
	if (return_code == IO_OK) {
L
Linus Torvalds 已提交
3226 3227 3228 3229
		hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
		hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33];
		hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34];
		hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35];
3230 3231
	} else {		/* send command failed */

L
Linus Torvalds 已提交
3232
		printk(KERN_WARNING "cciss: unable to determine firmware"
3233
		       " version of controller\n");
L
Linus Torvalds 已提交
3234
	}
3235 3236 3237 3238
	/* Get the number of logical volumes */
	return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,
			      sizeof(ReportLunData_struct), 0, 0, 0, NULL,
			      TYPE_CMD);
L
Linus Torvalds 已提交
3239

3240
	if (return_code == IO_OK) {
L
Linus Torvalds 已提交
3241 3242
#ifdef CCISS_DEBUG
		printk("LUN Data\n--------------------------\n");
3243 3244 3245 3246 3247 3248 3249 3250
#endif				/* CCISS_DEBUG */

		listlength |=
		    (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
		listlength |=
		    (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
		listlength |=
		    (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
L
Linus Torvalds 已提交
3251
		listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
3252 3253
	} else {		/* reading number of logical volumes failed */

L
Linus Torvalds 已提交
3254
		printk(KERN_WARNING "cciss: report logical volume"
3255
		       " command failed\n");
L
Linus Torvalds 已提交
3256 3257
		listlength = 0;
	}
3258 3259 3260 3261 3262
	hba[cntl_num]->num_luns = listlength / 8;	// 8 bytes pre entry
	if (hba[cntl_num]->num_luns > CISS_MAX_LUN) {
		printk(KERN_ERR
		       "ciss:  only %d number of logical volumes supported\n",
		       CISS_MAX_LUN);
L
Linus Torvalds 已提交
3263 3264 3265
		hba[cntl_num]->num_luns = CISS_MAX_LUN;
	}
#ifdef CCISS_DEBUG
3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283
	printk(KERN_DEBUG "Length = %x %x %x %x = %d\n",
	       ld_buff->LUNListLength[0], ld_buff->LUNListLength[1],
	       ld_buff->LUNListLength[2], ld_buff->LUNListLength[3],
	       hba[cntl_num]->num_luns);
#endif				/* CCISS_DEBUG */

	hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1;
	for (i = 0; i < CISS_MAX_LUN; i++) {
		if (i < hba[cntl_num]->num_luns) {
			lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
			    << 24;
			lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2]))
			    << 16;
			lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1]))
			    << 8;
			lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);

			hba[cntl_num]->drv[i].LunID = lunid;
L
Linus Torvalds 已提交
3284 3285

#ifdef CCISS_DEBUG
3286 3287 3288 3289 3290
			printk(KERN_DEBUG "LUN[%d]:  %x %x %x %x = %x\n", i,
			       ld_buff->LUN[i][0], ld_buff->LUN[i][1],
			       ld_buff->LUN[i][2], ld_buff->LUN[i][3],
			       hba[cntl_num]->drv[i].LunID);
#endif				/* CCISS_DEBUG */
3291 3292 3293 3294

		/* testing to see if 16-byte CDBs are already being used */
		if(hba[cntl_num]->cciss_read == CCISS_READ_16) {
			cciss_read_capacity_16(cntl_num, i, 0,
3295
					    &total_size, &block_size);
3296 3297 3298 3299
			goto geo_inq;
		}
		cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size);

3300 3301 3302
		/* If read_capacity returns all F's the logical is >2TB */
		/* so we switch to 16-byte CDBs for all read/write ops */
		if(total_size == 0xFFFFFFFFULL) {
3303 3304 3305 3306 3307 3308 3309 3310 3311
			cciss_read_capacity_16(cntl_num, i, 0,
			&total_size, &block_size);
			hba[cntl_num]->cciss_read = CCISS_READ_16;
			hba[cntl_num]->cciss_write = CCISS_WRITE_16;
		} else {
			hba[cntl_num]->cciss_read = CCISS_READ_10;
			hba[cntl_num]->cciss_write = CCISS_WRITE_10;
		}
geo_inq:
3312
			cciss_geometry_inquiry(cntl_num, i, 0, total_size,
3313 3314
					       block_size, inq_buff,
					       &hba[cntl_num]->drv[i]);
3315 3316 3317 3318
		} else {
			/* initialize raid_level to indicate a free space */
			hba[cntl_num]->drv[i].raid_level = -1;
		}
L
Linus Torvalds 已提交
3319 3320 3321
	}
	kfree(ld_buff);
	kfree(inq_buff);
3322
}
L
Linus Torvalds 已提交
3323 3324 3325 3326 3327

/* Function to find the first free pointer into our hba[] array */
/* Returns -1 if no free entries are left.  */
static int alloc_cciss_hba(void)
{
3328
	int i;
L
Linus Torvalds 已提交
3329

3330
	for (i = 0; i < MAX_CTLR; i++) {
L
Linus Torvalds 已提交
3331 3332
		if (!hba[i]) {
			ctlr_info_t *p;
J
Jesper Juhl 已提交
3333

3334
			p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
L
Linus Torvalds 已提交
3335 3336
			if (!p)
				goto Enomem;
3337
			p->gendisk[0] = alloc_disk(1 << NWD_SHIFT);
J
Jesper Juhl 已提交
3338 3339
			if (!p->gendisk[0]) {
				kfree(p);
3340
				goto Enomem;
J
Jesper Juhl 已提交
3341
			}
L
Linus Torvalds 已提交
3342 3343 3344 3345 3346
			hba[i] = p;
			return i;
		}
	}
	printk(KERN_WARNING "cciss: This driver supports a maximum"
3347
	       " of %d controllers.\n", MAX_CTLR);
3348 3349
	return -1;
Enomem:
L
Linus Torvalds 已提交
3350 3351 3352 3353 3354 3355 3356 3357 3358 3359
	printk(KERN_ERR "cciss: out of memory.\n");
	return -1;
}

static void free_hba(int i)
{
	ctlr_info_t *p = hba[i];
	int n;

	hba[i] = NULL;
3360
	for (n = 0; n < CISS_MAX_LUN; n++)
L
Linus Torvalds 已提交
3361 3362 3363 3364 3365 3366 3367 3368 3369 3370
		put_disk(p->gendisk[n]);
	kfree(p);
}

/*
 *  This is it.  Find all the controllers and register them.  I really hate
 *  stealing all these major device numbers.
 *  returns the number of block devices registered.
 */
static int __devinit cciss_init_one(struct pci_dev *pdev,
3371
				    const struct pci_device_id *ent)
L
Linus Torvalds 已提交
3372 3373
{
	int i;
3374
	int j = 0;
L
Linus Torvalds 已提交
3375
	int rc;
3376
	int dac;
L
Linus Torvalds 已提交
3377 3378

	i = alloc_cciss_hba();
3379
	if (i < 0)
3380
		return -1;
3381 3382 3383

	hba[i]->busy_initializing = 1;

L
Linus Torvalds 已提交
3384 3385 3386 3387 3388 3389 3390 3391
	if (cciss_pci_init(hba[i], pdev) != 0)
		goto clean1;

	sprintf(hba[i]->devname, "cciss%d", i);
	hba[i]->ctlr = i;
	hba[i]->pdev = pdev;

	/* configure PCI DMA stuff */
3392
	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
3393
		dac = 1;
3394
	else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
3395
		dac = 0;
L
Linus Torvalds 已提交
3396
	else {
3397
		printk(KERN_ERR "cciss: no suitable DMA available\n");
L
Linus Torvalds 已提交
3398 3399 3400 3401 3402 3403 3404 3405 3406
		goto clean1;
	}

	/*
	 * register with the major number, or get a dynamic major number
	 * by passing 0 as argument.  This is done for greater than
	 * 8 controller support.
	 */
	if (i < MAX_CTLR_ORIG)
3407
		hba[i]->major = COMPAQ_CISS_MAJOR + i;
L
Linus Torvalds 已提交
3408
	rc = register_blkdev(hba[i]->major, hba[i]->devname);
3409
	if (rc == -EBUSY || rc == -EINVAL) {
L
Linus Torvalds 已提交
3410
		printk(KERN_ERR
3411 3412
		       "cciss:  Unable to get major number %d for %s "
		       "on hba %d\n", hba[i]->major, hba[i]->devname, i);
L
Linus Torvalds 已提交
3413
		goto clean1;
3414
	} else {
L
Linus Torvalds 已提交
3415 3416 3417 3418 3419 3420
		if (i >= MAX_CTLR_ORIG)
			hba[i]->major = rc;
	}

	/* make sure the board interrupts are off */
	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
3421
	if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr,
3422
			IRQF_DISABLED | IRQF_SHARED, hba[i]->devname, hba[i])) {
L
Linus Torvalds 已提交
3423
		printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
3424
		       hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname);
L
Linus Torvalds 已提交
3425 3426
		goto clean2;
	}
3427 3428

	printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
3429 3430 3431 3432
	       hba[i]->devname, pdev->device, pci_name(pdev),
	       hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");

	hba[i]->cmd_pool_bits =
3433
	    kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG -
3434 3435 3436
		      1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
	hba[i]->cmd_pool = (CommandList_struct *)
	    pci_alloc_consistent(hba[i]->pdev,
3437
		    hba[i]->nr_cmds * sizeof(CommandList_struct),
3438 3439 3440
		    &(hba[i]->cmd_pool_dhandle));
	hba[i]->errinfo_pool = (ErrorInfo_struct *)
	    pci_alloc_consistent(hba[i]->pdev,
3441
		    hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
3442 3443 3444 3445 3446
		    &(hba[i]->errinfo_pool_dhandle));
	if ((hba[i]->cmd_pool_bits == NULL)
	    || (hba[i]->cmd_pool == NULL)
	    || (hba[i]->errinfo_pool == NULL)) {
		printk(KERN_ERR "cciss: out of memory");
L
Linus Torvalds 已提交
3447 3448
		goto clean4;
	}
3449
#ifdef CONFIG_CISS_SCSI_TAPE
3450 3451
	hba[i]->scsi_rejects.complete =
	    kmalloc(sizeof(hba[i]->scsi_rejects.complete[0]) *
3452
		    (hba[i]->nr_cmds + 5), GFP_KERNEL);
3453
	if (hba[i]->scsi_rejects.complete == NULL) {
3454
		printk(KERN_ERR "cciss: out of memory");
3455 3456 3457
		goto clean4;
	}
#endif
L
Linus Torvalds 已提交
3458 3459
	spin_lock_init(&hba[i]->lock);

3460 3461
	/* Initialize the pdev driver private data.
	   have it point to hba[i].  */
L
Linus Torvalds 已提交
3462
	pci_set_drvdata(pdev, hba[i]);
3463 3464 3465
	/* command and error info recs zeroed out before
	   they are used */
	memset(hba[i]->cmd_pool_bits, 0,
3466
	       ((hba[i]->nr_cmds + BITS_PER_LONG -
3467
		 1) / BITS_PER_LONG) * sizeof(unsigned long));
L
Linus Torvalds 已提交
3468

3469 3470 3471
#ifdef CCISS_DEBUG
	printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i);
#endif				/* CCISS_DEBUG */
L
Linus Torvalds 已提交
3472 3473 3474 3475 3476 3477 3478 3479 3480

	cciss_getgeometry(i);

	cciss_scsi_setup(i);

	/* Turn the interrupts on so we can service requests */
	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);

	cciss_procinit(i);
3481 3482 3483

	hba[i]->cciss_max_sectors = 2048;

3484
	hba[i]->busy_initializing = 0;
L
Linus Torvalds 已提交
3485

3486
	do {
M
Mike Miller 已提交
3487 3488
		drive_info_struct *drv = &(hba[i]->drv[j]);
		struct gendisk *disk = hba[i]->gendisk[j];
3489
		struct request_queue *q;
3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501

		/* Check if the disk was allocated already */
		if (!disk){
			hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT);
			disk = hba[i]->gendisk[j];
		}

		/* Check that the disk was able to be allocated */
		if (!disk) {
			printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j);
			goto clean4;
		}
M
Mike Miller 已提交
3502 3503 3504 3505

		q = blk_init_queue(do_cciss_request, &hba[i]->lock);
		if (!q) {
			printk(KERN_ERR
3506 3507
			       "cciss:  unable to allocate queue for disk %d\n",
			       j);
3508
			goto clean4;
M
Mike Miller 已提交
3509 3510 3511
		}
		drv->queue = q;

3512 3513 3514 3515
		blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);

		/* This is a hardware imposed limit. */
		blk_queue_max_hw_segments(q, MAXSGENTRIES);
L
Linus Torvalds 已提交
3516

3517 3518
		/* This is a limit in the driver and could be eliminated. */
		blk_queue_max_phys_segments(q, MAXSGENTRIES);
L
Linus Torvalds 已提交
3519

3520
		blk_queue_max_sectors(q, hba[i]->cciss_max_sectors);
L
Linus Torvalds 已提交
3521

3522
		blk_queue_softirq_done(q, cciss_softirq_done);
L
Linus Torvalds 已提交
3523

M
Mike Miller 已提交
3524
		q->queuedata = hba[i];
L
Linus Torvalds 已提交
3525 3526 3527 3528
		sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
		disk->major = hba[i]->major;
		disk->first_minor = j << NWD_SHIFT;
		disk->fops = &cciss_fops;
M
Mike Miller 已提交
3529
		disk->queue = q;
L
Linus Torvalds 已提交
3530
		disk->private_data = drv;
3531
		disk->driverfs_dev = &pdev->dev;
L
Linus Torvalds 已提交
3532 3533
		/* we must register the controller even if no disks exist */
		/* this is for the online array utilities */
3534
		if (!drv->heads && j)
L
Linus Torvalds 已提交
3535
			continue;
M
Mike Miller 已提交
3536
		blk_queue_hardsect_size(q, drv->block_size);
L
Linus Torvalds 已提交
3537
		set_capacity(disk, drv->nr_blocks);
3538 3539
		j++;
	} while (j <= hba[i]->highest_lun);
M
Mike Miller 已提交
3540

3541 3542 3543 3544 3545 3546 3547 3548
	/* Make sure all queue data is written out before */
	/* interrupt handler, triggered by add_disk,  */
	/* is allowed to start them. */
	wmb();

	for (j = 0; j <= hba[i]->highest_lun; j++)
		add_disk(hba[i]->gendisk[j]);

3549 3550 3551 3552
	/* we must register the controller even if no disks exist */
	if (hba[i]->highest_lun == -1)
		add_disk(hba[i]->gendisk[0]);

3553
	return 1;
L
Linus Torvalds 已提交
3554

3555
      clean4:
3556
#ifdef CONFIG_CISS_SCSI_TAPE
3557
	kfree(hba[i]->scsi_rejects.complete);
3558
#endif
3559
	kfree(hba[i]->cmd_pool_bits);
3560
	if (hba[i]->cmd_pool)
L
Linus Torvalds 已提交
3561
		pci_free_consistent(hba[i]->pdev,
3562
				    hba[i]->nr_cmds * sizeof(CommandList_struct),
3563 3564
				    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
	if (hba[i]->errinfo_pool)
L
Linus Torvalds 已提交
3565
		pci_free_consistent(hba[i]->pdev,
3566
				    hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
3567 3568
				    hba[i]->errinfo_pool,
				    hba[i]->errinfo_pool_dhandle);
3569
	free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
3570
      clean2:
L
Linus Torvalds 已提交
3571
	unregister_blkdev(hba[i]->major, hba[i]->devname);
3572
      clean1:
3573
	hba[i]->busy_initializing = 0;
3574 3575 3576 3577 3578 3579
	/* cleanup any queues that may have been initialized */
	for (j=0; j <= hba[i]->highest_lun; j++){
		drive_info_struct *drv = &(hba[i]->drv[j]);
		if (drv->queue)
			blk_cleanup_queue(drv->queue);
	}
3580 3581 3582 3583
	/*
	 * Deliberately omit pci_disable_device(): it does something nasty to
	 * Smart Array controllers that pci_enable_device does not undo
	 */
3584 3585
	pci_release_regions(pdev);
	pci_set_drvdata(pdev, NULL);
3586
	free_hba(i);
3587
	return -1;
L
Linus Torvalds 已提交
3588 3589
}

3590
static void cciss_shutdown(struct pci_dev *pdev)
L
Linus Torvalds 已提交
3591 3592
{
	ctlr_info_t *tmp_ptr;
3593
	int i;
L
Linus Torvalds 已提交
3594
	char flush_buf[4];
3595
	int return_code;
L
Linus Torvalds 已提交
3596

3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622
	tmp_ptr = pci_get_drvdata(pdev);
	if (tmp_ptr == NULL)
		return;
	i = tmp_ptr->ctlr;
	if (hba[i] == NULL)
		return;

	/* Turn board interrupts off  and send the flush cache command */
	/* sendcmd will turn off interrupt, and send the flush...
	 * To write all data in the battery backed cache to disks */
	memset(flush_buf, 0, 4);
	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
			      TYPE_CMD);
	if (return_code == IO_OK) {
		printk(KERN_INFO "Completed flushing cache on controller %d\n", i);
	} else {
		printk(KERN_WARNING "Error flushing cache on controller %d\n", i);
	}
	free_irq(hba[i]->intr[2], hba[i]);
}

static void __devexit cciss_remove_one(struct pci_dev *pdev)
{
	ctlr_info_t *tmp_ptr;
	int i, j;

3623 3624
	if (pci_get_drvdata(pdev) == NULL) {
		printk(KERN_ERR "cciss: Unable to remove device \n");
L
Linus Torvalds 已提交
3625 3626 3627 3628
		return;
	}
	tmp_ptr = pci_get_drvdata(pdev);
	i = tmp_ptr->ctlr;
3629
	if (hba[i] == NULL) {
L
Linus Torvalds 已提交
3630
		printk(KERN_ERR "cciss: device appears to "
3631
		       "already be removed \n");
L
Linus Torvalds 已提交
3632 3633
		return;
	}
3634 3635 3636 3637 3638 3639 3640 3641

	remove_proc_entry(hba[i]->devname, proc_cciss);
	unregister_blkdev(hba[i]->major, hba[i]->devname);

	/* remove it from the disk list */
	for (j = 0; j < CISS_MAX_LUN; j++) {
		struct gendisk *disk = hba[i]->gendisk[j];
		if (disk) {
3642
			struct request_queue *q = disk->queue;
3643 3644 3645 3646 3647 3648 3649 3650 3651 3652

			if (disk->flags & GENHD_FL_UP)
				del_gendisk(disk);
			if (q)
				blk_cleanup_queue(q);
		}
	}

	cciss_unregister_scsi(i);	/* unhook from SCSI subsystem */

3653
	cciss_shutdown(pdev);
3654 3655

#ifdef CONFIG_PCI_MSI
3656 3657 3658 3659 3660
	if (hba[i]->msix_vector)
		pci_disable_msix(hba[i]->pdev);
	else if (hba[i]->msi_vector)
		pci_disable_msi(hba[i]->pdev);
#endif				/* CONFIG_PCI_MSI */
3661

L
Linus Torvalds 已提交
3662 3663
	iounmap(hba[i]->vaddr);

3664
	pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct),
L
Linus Torvalds 已提交
3665
			    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
3666
	pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct),
3667
			    hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
L
Linus Torvalds 已提交
3668
	kfree(hba[i]->cmd_pool_bits);
3669 3670 3671
#ifdef CONFIG_CISS_SCSI_TAPE
	kfree(hba[i]->scsi_rejects.complete);
#endif
3672 3673 3674 3675
	/*
	 * Deliberately omit pci_disable_device(): it does something nasty to
	 * Smart Array controllers that pci_enable_device does not undo
	 */
3676
	pci_release_regions(pdev);
3677
	pci_set_drvdata(pdev, NULL);
L
Linus Torvalds 已提交
3678
	free_hba(i);
3679
}
L
Linus Torvalds 已提交
3680 3681

static struct pci_driver cciss_pci_driver = {
3682 3683 3684 3685
	.name = "cciss",
	.probe = cciss_init_one,
	.remove = __devexit_p(cciss_remove_one),
	.id_table = cciss_pci_device_id,	/* id_table */
3686
	.shutdown = cciss_shutdown,
L
Linus Torvalds 已提交
3687 3688 3689 3690
};

/*
 *  This is it.  Register the PCI driver information for the cards we control
3691
 *  the OS will call our registered routines when it finds one of our cards.
L
Linus Torvalds 已提交
3692 3693 3694 3695 3696 3697
 */
static int __init cciss_init(void)
{
	printk(KERN_INFO DRIVER_NAME "\n");

	/* Register for our PCI devices */
3698
	return pci_register_driver(&cciss_pci_driver);
L
Linus Torvalds 已提交
3699 3700 3701 3702 3703 3704 3705 3706
}

static void __exit cciss_cleanup(void)
{
	int i;

	pci_unregister_driver(&cciss_pci_driver);
	/* double check that all controller entrys have been removed */
3707 3708
	for (i = 0; i < MAX_CTLR; i++) {
		if (hba[i] != NULL) {
L
Linus Torvalds 已提交
3709
			printk(KERN_WARNING "cciss: had to remove"
3710
			       " controller %d\n", i);
L
Linus Torvalds 已提交
3711 3712 3713
			cciss_remove_one(hba[i]->pdev);
		}
	}
A
Alexey Dobriyan 已提交
3714
	remove_proc_entry("driver/cciss", NULL);
L
Linus Torvalds 已提交
3715 3716
}

3717 3718 3719 3720 3721 3722 3723 3724
static void fail_all_cmds(unsigned long ctlr)
{
	/* If we get here, the board is apparently dead. */
	ctlr_info_t *h = hba[ctlr];
	CommandList_struct *c;
	unsigned long flags;

	printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr);
3725
	h->alive = 0;		/* the controller apparently died... */
3726 3727 3728

	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);

3729
	pci_disable_device(h->pdev);	/* Make sure it is really dead. */
3730 3731

	/* move everything off the request queue onto the completed queue */
3732
	while ((c = h->reqQ) != NULL) {
3733 3734
		removeQ(&(h->reqQ), c);
		h->Qdepth--;
3735
		addQ(&(h->cmpQ), c);
3736 3737 3738
	}

	/* Now, fail everything on the completed queue with a HW error */
3739
	while ((c = h->cmpQ) != NULL) {
3740 3741 3742 3743 3744 3745 3746
		removeQ(&h->cmpQ, c);
		c->err_info->CommandStatus = CMD_HARDWARE_ERR;
		if (c->cmd_type == CMD_RWREQ) {
			complete_command(h, c, 0);
		} else if (c->cmd_type == CMD_IOCTL_PEND)
			complete(c->waiting);
#ifdef CONFIG_CISS_SCSI_TAPE
3747 3748
		else if (c->cmd_type == CMD_SCSI)
			complete_scsi_command(c, 0, 0);
3749 3750 3751 3752 3753 3754
#endif
	}
	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
	return;
}

L
Linus Torvalds 已提交
3755 3756
module_init(cciss_init);
module_exit(cciss_cleanup);