blob: ab2f8b26790857e2388564aaa58688df5598c70c [file] [log] [blame]
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +08001/*
2 * HighPoint RR3xxx controller driver for Linux
3 * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * Please report bugs/comments/suggestions to linux@highpoint-tech.com
15 *
16 * For more information, visit http://www.highpoint-tech.com
17 */
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/string.h>
22#include <linux/kernel.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25#include <linux/errno.h>
26#include <linux/delay.h>
27#include <linux/timer.h>
28#include <linux/spinlock.h>
29#include <linux/hdreg.h>
30#include <asm/uaccess.h>
31#include <asm/io.h>
32#include <asm/div64.h>
33#include <scsi/scsi_cmnd.h>
34#include <scsi/scsi_device.h>
35#include <scsi/scsi.h>
36#include <scsi/scsi_tcq.h>
37#include <scsi/scsi_host.h>
38
39#include "hptiop.h"
40
41MODULE_AUTHOR("HighPoint Technologies, Inc.");
42MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver");
43
44static char driver_name[] = "hptiop";
45static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver";
46static const char driver_ver[] = "v1.0 (060426)";
47
48static DEFINE_SPINLOCK(hptiop_hba_list_lock);
49static LIST_HEAD(hptiop_hba_list);
50static int hptiop_cdev_major = -1;
51
52static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag);
53static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag);
54static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg);
55
56static inline void hptiop_pci_posting_flush(struct hpt_iopmu __iomem *iop)
57{
58 readl(&iop->outbound_intstatus);
59}
60
61static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec)
62{
63 u32 req = 0;
64 int i;
65
66 for (i = 0; i < millisec; i++) {
67 req = readl(&iop->inbound_queue);
68 if (req != IOPMU_QUEUE_EMPTY)
69 break;
70 msleep(1);
71 }
72
73 if (req != IOPMU_QUEUE_EMPTY) {
74 writel(req, &iop->outbound_queue);
75 hptiop_pci_posting_flush(iop);
76 return 0;
77 }
78
79 return -1;
80}
81
82static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag)
83{
84 if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT)
85 return hptiop_host_request_callback(hba,
86 tag & ~IOPMU_QUEUE_ADDR_HOST_BIT);
87 else
88 return hptiop_iop_request_callback(hba, tag);
89}
90
91static inline void hptiop_drain_outbound_queue(struct hptiop_hba *hba)
92{
93 u32 req;
94
95 while ((req = readl(&hba->iop->outbound_queue)) != IOPMU_QUEUE_EMPTY) {
96
97 if (req & IOPMU_QUEUE_MASK_HOST_BITS)
98 hptiop_request_callback(hba, req);
99 else {
100 struct hpt_iop_request_header __iomem * p;
101
102 p = (struct hpt_iop_request_header __iomem *)
103 ((char __iomem *)hba->iop + req);
104
105 if (readl(&p->flags) & IOP_REQUEST_FLAG_SYNC_REQUEST) {
106 if (readl(&p->context))
107 hptiop_request_callback(hba, req);
108 else
109 writel(1, &p->context);
110 }
111 else
112 hptiop_request_callback(hba, req);
113 }
114 }
115}
116
117static int __iop_intr(struct hptiop_hba *hba)
118{
119 struct hpt_iopmu __iomem *iop = hba->iop;
120 u32 status;
121 int ret = 0;
122
123 status = readl(&iop->outbound_intstatus);
124
125 if (status & IOPMU_OUTBOUND_INT_MSG0) {
126 u32 msg = readl(&iop->outbound_msgaddr0);
127 dprintk("received outbound msg %x\n", msg);
128 writel(IOPMU_OUTBOUND_INT_MSG0, &iop->outbound_intstatus);
129 hptiop_message_callback(hba, msg);
130 ret = 1;
131 }
132
133 if (status & IOPMU_OUTBOUND_INT_POSTQUEUE) {
134 hptiop_drain_outbound_queue(hba);
135 ret = 1;
136 }
137
138 return ret;
139}
140
141static int iop_send_sync_request(struct hptiop_hba *hba,
142 void __iomem *_req, u32 millisec)
143{
144 struct hpt_iop_request_header __iomem *req = _req;
145 u32 i;
146
147 writel(readl(&req->flags) | IOP_REQUEST_FLAG_SYNC_REQUEST,
148 &req->flags);
149
150 writel(0, &req->context);
151
152 writel((unsigned long)req - (unsigned long)hba->iop,
153 &hba->iop->inbound_queue);
154
155 hptiop_pci_posting_flush(hba->iop);
156
157 for (i = 0; i < millisec; i++) {
158 __iop_intr(hba);
159 if (readl(&req->context))
160 return 0;
161 msleep(1);
162 }
163
164 return -1;
165}
166
167static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec)
168{
169 u32 i;
170
171 hba->msg_done = 0;
172
173 writel(msg, &hba->iop->inbound_msgaddr0);
174
175 hptiop_pci_posting_flush(hba->iop);
176
177 for (i = 0; i < millisec; i++) {
178 spin_lock_irq(hba->host->host_lock);
179 __iop_intr(hba);
180 spin_unlock_irq(hba->host->host_lock);
181 if (hba->msg_done)
182 break;
183 msleep(1);
184 }
185
186 return hba->msg_done? 0 : -1;
187}
188
189static int iop_get_config(struct hptiop_hba *hba,
190 struct hpt_iop_request_get_config *config)
191{
192 u32 req32;
193 struct hpt_iop_request_get_config __iomem *req;
194
195 req32 = readl(&hba->iop->inbound_queue);
196 if (req32 == IOPMU_QUEUE_EMPTY)
197 return -1;
198
199 req = (struct hpt_iop_request_get_config __iomem *)
200 ((unsigned long)hba->iop + req32);
201
202 writel(0, &req->header.flags);
203 writel(IOP_REQUEST_TYPE_GET_CONFIG, &req->header.type);
204 writel(sizeof(struct hpt_iop_request_get_config), &req->header.size);
205 writel(IOP_RESULT_PENDING, &req->header.result);
206
207 if (iop_send_sync_request(hba, req, 20000)) {
208 dprintk("Get config send cmd failed\n");
209 return -1;
210 }
211
212 memcpy_fromio(config, req, sizeof(*config));
213 writel(req32, &hba->iop->outbound_queue);
214 return 0;
215}
216
217static int iop_set_config(struct hptiop_hba *hba,
218 struct hpt_iop_request_set_config *config)
219{
220 u32 req32;
221 struct hpt_iop_request_set_config __iomem *req;
222
223 req32 = readl(&hba->iop->inbound_queue);
224 if (req32 == IOPMU_QUEUE_EMPTY)
225 return -1;
226
227 req = (struct hpt_iop_request_set_config __iomem *)
228 ((unsigned long)hba->iop + req32);
229
230 memcpy_toio((u8 __iomem *)req + sizeof(struct hpt_iop_request_header),
231 (u8 *)config + sizeof(struct hpt_iop_request_header),
232 sizeof(struct hpt_iop_request_set_config) -
233 sizeof(struct hpt_iop_request_header));
234
235 writel(0, &req->header.flags);
236 writel(IOP_REQUEST_TYPE_SET_CONFIG, &req->header.type);
237 writel(sizeof(struct hpt_iop_request_set_config), &req->header.size);
238 writel(IOP_RESULT_PENDING, &req->header.result);
239
240 if (iop_send_sync_request(hba, req, 20000)) {
241 dprintk("Set config send cmd failed\n");
242 return -1;
243 }
244
245 writel(req32, &hba->iop->outbound_queue);
246 return 0;
247}
248
249static int hptiop_initialize_iop(struct hptiop_hba *hba)
250{
251 struct hpt_iopmu __iomem *iop = hba->iop;
252
253 /* enable interrupts */
254 writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0),
255 &iop->outbound_intmask);
256
257 hba->initialized = 1;
258
259 /* start background tasks */
260 if (iop_send_sync_msg(hba,
261 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) {
262 printk(KERN_ERR "scsi%d: fail to start background task\n",
263 hba->host->host_no);
264 return -1;
265 }
266 return 0;
267}
268
269static int hptiop_map_pci_bar(struct hptiop_hba *hba)
270{
271 u32 mem_base_phy, length;
272 void __iomem *mem_base_virt;
273 struct pci_dev *pcidev = hba->pcidev;
274
275 if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
276 printk(KERN_ERR "scsi%d: pci resource invalid\n",
277 hba->host->host_no);
278 return -1;
279 }
280
281 mem_base_phy = pci_resource_start(pcidev, 0);
282 length = pci_resource_len(pcidev, 0);
283 mem_base_virt = ioremap(mem_base_phy, length);
284
285 if (!mem_base_virt) {
286 printk(KERN_ERR "scsi%d: Fail to ioremap memory space\n",
287 hba->host->host_no);
288 return -1;
289 }
290
291 hba->iop = mem_base_virt;
292 dprintk("hptiop_map_pci_bar: iop=%p\n", hba->iop);
293 return 0;
294}
295
296static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg)
297{
298 dprintk("iop message 0x%x\n", msg);
299
300 if (!hba->initialized)
301 return;
302
303 if (msg == IOPMU_INBOUND_MSG0_RESET) {
304 atomic_set(&hba->resetting, 0);
305 wake_up(&hba->reset_wq);
306 }
307 else if (msg <= IOPMU_INBOUND_MSG0_MAX)
308 hba->msg_done = 1;
309}
310
311static inline struct hptiop_request *get_req(struct hptiop_hba *hba)
312{
313 struct hptiop_request *ret;
314
315 dprintk("get_req : req=%p\n", hba->req_list);
316
317 ret = hba->req_list;
318 if (ret)
319 hba->req_list = ret->next;
320
321 return ret;
322}
323
324static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req)
325{
326 dprintk("free_req(%d, %p)\n", req->index, req);
327 req->next = hba->req_list;
328 hba->req_list = req;
329}
330
331static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag)
332{
333 struct hpt_iop_request_scsi_command *req;
334 struct scsi_cmnd *scp;
335
336 req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt;
337 dprintk("hptiop_host_request_callback: req=%p, type=%d, "
338 "result=%d, context=0x%x tag=%d\n",
339 req, req->header.type, req->header.result,
340 req->header.context, tag);
341
342 BUG_ON(!req->header.result);
343 BUG_ON(req->header.type != cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND));
344
345 scp = hba->reqs[tag].scp;
346
347 if (HPT_SCP(scp)->mapped) {
348 if (scp->use_sg)
349 pci_unmap_sg(hba->pcidev,
350 (struct scatterlist *)scp->request_buffer,
351 scp->use_sg,
352 scp->sc_data_direction
353 );
354 else
355 pci_unmap_single(hba->pcidev,
356 HPT_SCP(scp)->dma_handle,
357 scp->request_bufflen,
358 scp->sc_data_direction
359 );
360 }
361
362 switch (le32_to_cpu(req->header.result)) {
363 case IOP_RESULT_SUCCESS:
364 scp->result = (DID_OK<<16);
365 break;
366 case IOP_RESULT_BAD_TARGET:
367 scp->result = (DID_BAD_TARGET<<16);
368 break;
369 case IOP_RESULT_BUSY:
370 scp->result = (DID_BUS_BUSY<<16);
371 break;
372 case IOP_RESULT_RESET:
373 scp->result = (DID_RESET<<16);
374 break;
375 case IOP_RESULT_FAIL:
376 scp->result = (DID_ERROR<<16);
377 break;
378 case IOP_RESULT_INVALID_REQUEST:
379 scp->result = (DID_ABORT<<16);
380 break;
381 case IOP_RESULT_MODE_SENSE_CHECK_CONDITION:
382 scp->result = SAM_STAT_CHECK_CONDITION;
383 memset(&scp->sense_buffer,
384 0, sizeof(scp->sense_buffer));
385 memcpy(&scp->sense_buffer,
386 &req->sg_list, le32_to_cpu(req->dataxfer_length));
387 break;
388
389 default:
390 scp->result = ((DRIVER_INVALID|SUGGEST_ABORT)<<24) |
391 (DID_ABORT<<16);
392 break;
393 }
394
395 dprintk("scsi_done(%p)\n", scp);
396 scp->scsi_done(scp);
397 free_req(hba, &hba->reqs[tag]);
398}
399
400void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag)
401{
402 struct hpt_iop_request_header __iomem *req;
403 struct hpt_iop_request_ioctl_command __iomem *p;
404 struct hpt_ioctl_k *arg;
405
406 req = (struct hpt_iop_request_header __iomem *)
407 ((unsigned long)hba->iop + tag);
408 dprintk("hptiop_iop_request_callback: req=%p, type=%d, "
409 "result=%d, context=0x%x tag=%d\n",
410 req, readl(&req->type), readl(&req->result),
411 readl(&req->context), tag);
412
413 BUG_ON(!readl(&req->result));
414 BUG_ON(readl(&req->type) != IOP_REQUEST_TYPE_IOCTL_COMMAND);
415
416 p = (struct hpt_iop_request_ioctl_command __iomem *)req;
417 arg = (struct hpt_ioctl_k *)(unsigned long)
418 (readl(&req->context) |
419 ((u64)readl(&req->context_hi32)<<32));
420
421 if (readl(&req->result) == IOP_RESULT_SUCCESS) {
422 arg->result = HPT_IOCTL_RESULT_OK;
423
424 if (arg->outbuf_size)
425 memcpy_fromio(arg->outbuf,
426 &p->buf[(readl(&p->inbuf_size) + 3)& ~3],
427 arg->outbuf_size);
428
429 if (arg->bytes_returned)
430 *arg->bytes_returned = arg->outbuf_size;
431 }
432 else
433 arg->result = HPT_IOCTL_RESULT_FAILED;
434
435 arg->done(arg);
436 writel(tag, &hba->iop->outbound_queue);
437}
438
439static irqreturn_t hptiop_intr(int irq, void *dev_id, struct pt_regs *regs)
440{
441 struct hptiop_hba *hba = dev_id;
442 int handled;
443 unsigned long flags;
444
445 spin_lock_irqsave(hba->host->host_lock, flags);
446 handled = __iop_intr(hba);
447 spin_unlock_irqrestore(hba->host->host_lock, flags);
448
449 return handled;
450}
451
452static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg)
453{
454 struct Scsi_Host *host = scp->device->host;
455 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
456 struct scatterlist *sglist = (struct scatterlist *)scp->request_buffer;
457
458 /*
459 * though we'll not get non-use_sg fields anymore,
460 * keep use_sg checking anyway
461 */
462 if (scp->use_sg) {
463 int idx;
464
465 HPT_SCP(scp)->sgcnt = pci_map_sg(hba->pcidev,
466 sglist, scp->use_sg,
467 scp->sc_data_direction);
468 HPT_SCP(scp)->mapped = 1;
469 BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors);
470
471 for (idx = 0; idx < HPT_SCP(scp)->sgcnt; idx++) {
472 psg[idx].pci_address =
473 cpu_to_le64(sg_dma_address(&sglist[idx]));
474 psg[idx].size = cpu_to_le32(sg_dma_len(&sglist[idx]));
475 psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ?
476 cpu_to_le32(1) : 0;
477 }
478
479 return HPT_SCP(scp)->sgcnt;
480 } else {
481 HPT_SCP(scp)->dma_handle = pci_map_single(
482 hba->pcidev,
483 scp->request_buffer,
484 scp->request_bufflen,
485 scp->sc_data_direction
486 );
487 HPT_SCP(scp)->mapped = 1;
488 psg->pci_address = cpu_to_le64(HPT_SCP(scp)->dma_handle);
489 psg->size = cpu_to_le32(scp->request_bufflen);
490 psg->eot = cpu_to_le32(1);
491 return 1;
492 }
493}
494
495static int hptiop_queuecommand(struct scsi_cmnd *scp,
496 void (*done)(struct scsi_cmnd *))
497{
498 struct Scsi_Host *host = scp->device->host;
499 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
500 struct hpt_iop_request_scsi_command *req;
501 int sg_count = 0;
502 struct hptiop_request *_req;
503
504 BUG_ON(!done);
505 scp->scsi_done = done;
506
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +0800507 _req = get_req(hba);
508 if (_req == NULL) {
509 dprintk("hptiop_queuecmd : no free req\n");
HighPoint Linux Team4f2ddba2006-06-14 16:50:57 +0800510 return SCSI_MLQUEUE_HOST_BUSY;
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +0800511 }
512
513 _req->scp = scp;
514
515 dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%x-%x-%x) "
516 "req_index=%d, req=%p\n",
517 scp,
518 host->host_no, scp->device->channel,
519 scp->device->id, scp->device->lun,
520 *((u32 *)&scp->cmnd),
521 *((u32 *)&scp->cmnd + 1),
522 *((u32 *)&scp->cmnd + 2),
523 _req->index, _req->req_virt);
524
525 scp->result = 0;
526
527 if (scp->device->channel || scp->device->lun ||
528 scp->device->id > hba->max_devices) {
529 scp->result = DID_BAD_TARGET << 16;
530 free_req(hba, _req);
531 goto cmd_done;
532 }
533
534 req = (struct hpt_iop_request_scsi_command *)_req->req_virt;
535
536 /* build S/G table */
537 if (scp->request_bufflen)
538 sg_count = hptiop_buildsgl(scp, req->sg_list);
539 else
540 HPT_SCP(scp)->mapped = 0;
541
542 req->header.flags = cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT);
543 req->header.type = cpu_to_le32(IOP_REQUEST_TYPE_SCSI_COMMAND);
544 req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
545 req->header.context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT |
546 (u32)_req->index);
547 req->header.context_hi32 = 0;
James Bottomley6db874f2006-06-13 21:40:34 -0500548 req->dataxfer_length = cpu_to_le32(scp->request_bufflen);
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +0800549 req->channel = scp->device->channel;
550 req->target = scp->device->id;
551 req->lun = scp->device->lun;
552 req->header.size = cpu_to_le32(
553 sizeof(struct hpt_iop_request_scsi_command)
554 - sizeof(struct hpt_iopsg)
555 + sg_count * sizeof(struct hpt_iopsg));
556
557 memcpy(req->cdb, scp->cmnd, sizeof(req->cdb));
558
559 writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy,
560 &hba->iop->inbound_queue);
561
562 return 0;
563
564cmd_done:
565 dprintk("scsi_done(scp=%p)\n", scp);
566 scp->scsi_done(scp);
567 return 0;
568}
569
570static const char *hptiop_info(struct Scsi_Host *host)
571{
572 return driver_name_long;
573}
574
575static int hptiop_reset_hba(struct hptiop_hba *hba)
576{
577 if (atomic_xchg(&hba->resetting, 1) == 0) {
578 atomic_inc(&hba->reset_count);
579 writel(IOPMU_INBOUND_MSG0_RESET,
580 &hba->iop->outbound_msgaddr0);
581 hptiop_pci_posting_flush(hba->iop);
582 }
583
584 wait_event_timeout(hba->reset_wq,
585 atomic_read(&hba->resetting) == 0, 60 * HZ);
586
587 if (atomic_read(&hba->resetting)) {
588 /* IOP is in unkown state, abort reset */
589 printk(KERN_ERR "scsi%d: reset failed\n", hba->host->host_no);
590 return -1;
591 }
592
593 if (iop_send_sync_msg(hba,
594 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 5000)) {
595 dprintk("scsi%d: fail to start background task\n",
596 hba->host->host_no);
597 }
598
599 return 0;
600}
601
602static int hptiop_reset(struct scsi_cmnd *scp)
603{
604 struct Scsi_Host * host = scp->device->host;
605 struct hptiop_hba * hba = (struct hptiop_hba *)host->hostdata;
606
607 printk(KERN_WARNING "hptiop_reset(%d/%d/%d) scp=%p\n",
608 scp->device->host->host_no, scp->device->channel,
609 scp->device->id, scp);
610
611 return hptiop_reset_hba(hba)? FAILED : SUCCESS;
612}
613
614static int hptiop_adjust_disk_queue_depth(struct scsi_device *sdev,
615 int queue_depth)
616{
617 if(queue_depth > 256)
618 queue_depth = 256;
619 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
620 return queue_depth;
621}
622
623struct hptiop_getinfo {
624 char __user *buffer;
625 loff_t buflength;
626 loff_t bufoffset;
627 loff_t buffillen;
628 loff_t filpos;
629};
630
631static void hptiop_copy_mem_info(struct hptiop_getinfo *pinfo,
632 char *data, int datalen)
633{
634 if (pinfo->filpos < pinfo->bufoffset) {
635 if (pinfo->filpos + datalen <= pinfo->bufoffset) {
636 pinfo->filpos += datalen;
637 return;
638 } else {
639 data += (pinfo->bufoffset - pinfo->filpos);
640 datalen -= (pinfo->bufoffset - pinfo->filpos);
641 pinfo->filpos = pinfo->bufoffset;
642 }
643 }
644
645 pinfo->filpos += datalen;
646 if (pinfo->buffillen == pinfo->buflength)
647 return;
648
649 if (pinfo->buflength - pinfo->buffillen < datalen)
650 datalen = pinfo->buflength - pinfo->buffillen;
651
652 if (copy_to_user(pinfo->buffer + pinfo->buffillen, data, datalen))
653 return;
654
655 pinfo->buffillen += datalen;
656}
657
658static int hptiop_copy_info(struct hptiop_getinfo *pinfo, char *fmt, ...)
659{
660 va_list args;
661 char buf[128];
662 int len;
663
664 va_start(args, fmt);
665 len = vsnprintf(buf, sizeof(buf), fmt, args);
666 va_end(args);
667 hptiop_copy_mem_info(pinfo, buf, len);
668 return len;
669}
670
671static void hptiop_ioctl_done(struct hpt_ioctl_k *arg)
672{
673 arg->done = NULL;
674 wake_up(&arg->hba->ioctl_wq);
675}
676
677static void hptiop_do_ioctl(struct hpt_ioctl_k *arg)
678{
679 struct hptiop_hba *hba = arg->hba;
680 u32 val;
681 struct hpt_iop_request_ioctl_command __iomem *req;
682 int ioctl_retry = 0;
683
684 dprintk("scsi%d: hptiop_do_ioctl\n", hba->host->host_no);
685
686 /*
687 * check (in + out) buff size from application.
688 * outbuf must be dword aligned.
689 */
690 if (((arg->inbuf_size + 3) & ~3) + arg->outbuf_size >
691 hba->max_request_size
692 - sizeof(struct hpt_iop_request_header)
693 - 4 * sizeof(u32)) {
694 dprintk("scsi%d: ioctl buf size (%d/%d) is too large\n",
695 hba->host->host_no,
696 arg->inbuf_size, arg->outbuf_size);
697 arg->result = HPT_IOCTL_RESULT_FAILED;
698 return;
699 }
700
701retry:
702 spin_lock_irq(hba->host->host_lock);
703
704 val = readl(&hba->iop->inbound_queue);
705 if (val == IOPMU_QUEUE_EMPTY) {
706 spin_unlock_irq(hba->host->host_lock);
707 dprintk("scsi%d: no free req for ioctl\n", hba->host->host_no);
708 arg->result = -1;
709 return;
710 }
711
712 req = (struct hpt_iop_request_ioctl_command __iomem *)
713 ((unsigned long)hba->iop + val);
714
715 writel(HPT_CTL_CODE_LINUX_TO_IOP(arg->ioctl_code),
716 &req->ioctl_code);
717 writel(arg->inbuf_size, &req->inbuf_size);
718 writel(arg->outbuf_size, &req->outbuf_size);
719
720 /*
721 * use the buffer on the IOP local memory first, then copy it
722 * back to host.
723 * the caller's request buffer shoudl be little-endian.
724 */
725 if (arg->inbuf_size)
726 memcpy_toio(req->buf, arg->inbuf, arg->inbuf_size);
727
728 /* correct the controller ID for IOP */
729 if ((arg->ioctl_code == HPT_IOCTL_GET_CHANNEL_INFO ||
730 arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO_V2 ||
731 arg->ioctl_code == HPT_IOCTL_GET_CONTROLLER_INFO)
732 && arg->inbuf_size >= sizeof(u32))
733 writel(0, req->buf);
734
735 writel(IOP_REQUEST_TYPE_IOCTL_COMMAND, &req->header.type);
736 writel(0, &req->header.flags);
737 writel(offsetof(struct hpt_iop_request_ioctl_command, buf)
738 + arg->inbuf_size, &req->header.size);
739 writel((u32)(unsigned long)arg, &req->header.context);
740 writel(BITS_PER_LONG > 32 ? (u32)((unsigned long)arg>>32) : 0,
741 &req->header.context_hi32);
742 writel(IOP_RESULT_PENDING, &req->header.result);
743
744 arg->result = HPT_IOCTL_RESULT_FAILED;
745 arg->done = hptiop_ioctl_done;
746
747 writel(val, &hba->iop->inbound_queue);
748 hptiop_pci_posting_flush(hba->iop);
749
750 spin_unlock_irq(hba->host->host_lock);
751
752 wait_event_timeout(hba->ioctl_wq, arg->done == NULL, 60 * HZ);
753
754 if (arg->done != NULL) {
755 hptiop_reset_hba(hba);
756 if (ioctl_retry++ < 3)
757 goto retry;
758 }
759
760 dprintk("hpt_iop_ioctl %x result %d\n",
761 arg->ioctl_code, arg->result);
762}
763
764static int __hpt_do_ioctl(struct hptiop_hba *hba, u32 code, void *inbuf,
765 u32 insize, void *outbuf, u32 outsize)
766{
767 struct hpt_ioctl_k arg;
768 arg.hba = hba;
769 arg.ioctl_code = code;
770 arg.inbuf = inbuf;
771 arg.outbuf = outbuf;
772 arg.inbuf_size = insize;
773 arg.outbuf_size = outsize;
774 arg.bytes_returned = NULL;
775 hptiop_do_ioctl(&arg);
776 return arg.result;
777}
778
779static inline int hpt_id_valid(__le32 id)
780{
781 return id != 0 && id != cpu_to_le32(0xffffffff);
782}
783
784static int hptiop_get_controller_info(struct hptiop_hba *hba,
785 struct hpt_controller_info *pinfo)
786{
787 int id = 0;
788
789 return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CONTROLLER_INFO,
790 &id, sizeof(int), pinfo, sizeof(*pinfo));
791}
792
793
794static int hptiop_get_channel_info(struct hptiop_hba *hba, int bus,
795 struct hpt_channel_info *pinfo)
796{
797 u32 ids[2];
798
799 ids[0] = 0;
800 ids[1] = bus;
801 return __hpt_do_ioctl(hba, HPT_IOCTL_GET_CHANNEL_INFO,
802 ids, sizeof(ids), pinfo, sizeof(*pinfo));
803
804}
805
806static int hptiop_get_logical_devices(struct hptiop_hba *hba,
807 __le32 *pids, int maxcount)
808{
809 int i;
810 u32 count = maxcount - 1;
811
812 if (__hpt_do_ioctl(hba, HPT_IOCTL_GET_LOGICAL_DEVICES,
813 &count, sizeof(u32),
814 pids, sizeof(u32) * maxcount))
815 return -1;
816
817 maxcount = le32_to_cpu(pids[0]);
818 for (i = 0; i < maxcount; i++)
819 pids[i] = pids[i+1];
820
821 return maxcount;
822}
823
824static int hptiop_get_device_info_v3(struct hptiop_hba *hba, __le32 id,
825 struct hpt_logical_device_info_v3 *pinfo)
826{
827 return __hpt_do_ioctl(hba, HPT_IOCTL_GET_DEVICE_INFO_V3,
828 &id, sizeof(u32),
829 pinfo, sizeof(*pinfo));
830}
831
832static const char *get_array_status(struct hpt_logical_device_info_v3 *devinfo)
833{
834 static char s[64];
835 u32 flags = le32_to_cpu(devinfo->u.array.flags);
836 u32 trans_prog = le32_to_cpu(devinfo->u.array.transforming_progress);
837 u32 reb_prog = le32_to_cpu(devinfo->u.array.rebuilding_progress);
838
839 if (flags & ARRAY_FLAG_DISABLED)
840 return "Disabled";
841 else if (flags & ARRAY_FLAG_TRANSFORMING)
842 sprintf(s, "Expanding/Migrating %d.%d%%%s%s",
843 trans_prog / 100,
844 trans_prog % 100,
845 (flags & (ARRAY_FLAG_NEEDBUILDING|ARRAY_FLAG_BROKEN))?
846 ", Critical" : "",
847 ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
848 !(flags & ARRAY_FLAG_REBUILDING) &&
849 !(flags & ARRAY_FLAG_INITIALIZING))?
850 ", Unintialized" : "");
851 else if ((flags & ARRAY_FLAG_BROKEN) &&
852 devinfo->u.array.array_type != AT_RAID6)
853 return "Critical";
854 else if (flags & ARRAY_FLAG_REBUILDING)
855 sprintf(s,
856 (flags & ARRAY_FLAG_NEEDINITIALIZING)?
857 "%sBackground initializing %d.%d%%" :
858 "%sRebuilding %d.%d%%",
859 (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
860 reb_prog / 100,
861 reb_prog % 100);
862 else if (flags & ARRAY_FLAG_VERIFYING)
863 sprintf(s, "%sVerifying %d.%d%%",
864 (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
865 reb_prog / 100,
866 reb_prog % 100);
867 else if (flags & ARRAY_FLAG_INITIALIZING)
868 sprintf(s, "%sForground initializing %d.%d%%",
869 (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
870 reb_prog / 100,
871 reb_prog % 100);
872 else if (flags & ARRAY_FLAG_NEEDTRANSFORM)
873 sprintf(s,"%s%s%s", "Need Expanding/Migrating",
874 (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "",
875 ((flags & ARRAY_FLAG_NEEDINITIALIZING) &&
876 !(flags & ARRAY_FLAG_REBUILDING) &&
877 !(flags & ARRAY_FLAG_INITIALIZING))?
878 ", Unintialized" : "");
879 else if (flags & ARRAY_FLAG_NEEDINITIALIZING &&
880 !(flags & ARRAY_FLAG_REBUILDING) &&
881 !(flags & ARRAY_FLAG_INITIALIZING))
882 sprintf(s,"%sUninitialized",
883 (flags & ARRAY_FLAG_BROKEN)? "Critical, " : "");
884 else if ((flags & ARRAY_FLAG_NEEDBUILDING) ||
885 (flags & ARRAY_FLAG_BROKEN))
886 return "Critical";
887 else
888 return "Normal";
889 return s;
890}
891
892static void hptiop_dump_devinfo(struct hptiop_hba *hba,
893 struct hptiop_getinfo *pinfo, __le32 id, int indent)
894{
895 struct hpt_logical_device_info_v3 devinfo;
896 int i;
897 u64 capacity;
898
899 for (i = 0; i < indent; i++)
900 hptiop_copy_info(pinfo, "\t");
901
902 if (hptiop_get_device_info_v3(hba, id, &devinfo)) {
903 hptiop_copy_info(pinfo, "unknown\n");
904 return;
905 }
906
907 switch (devinfo.type) {
908
909 case LDT_DEVICE: {
910 struct hd_driveid *driveid;
911 u32 flags = le32_to_cpu(devinfo.u.device.flags);
912
913 driveid = (struct hd_driveid *)devinfo.u.device.ident;
914 /* model[] is 40 chars long, but we just want 20 chars here */
915 driveid->model[20] = 0;
916
917 if (indent)
918 if (flags & DEVICE_FLAG_DISABLED)
919 hptiop_copy_info(pinfo,"Missing\n");
920 else
921 hptiop_copy_info(pinfo, "CH%d %s\n",
922 devinfo.u.device.path_id + 1,
923 driveid->model);
924 else {
925 capacity = le64_to_cpu(devinfo.capacity) * 512;
926 do_div(capacity, 1000000);
927 hptiop_copy_info(pinfo,
928 "CH%d %s, %lluMB, %s %s%s%s%s\n",
929 devinfo.u.device.path_id + 1,
930 driveid->model,
931 capacity,
932 (flags & DEVICE_FLAG_DISABLED)?
933 "Disabled" : "Normal",
934 devinfo.u.device.read_ahead_enabled?
935 "[RA]" : "",
936 devinfo.u.device.write_cache_enabled?
937 "[WC]" : "",
938 devinfo.u.device.TCQ_enabled?
939 "[TCQ]" : "",
940 devinfo.u.device.NCQ_enabled?
941 "[NCQ]" : ""
942 );
943 }
944 break;
945 }
946
947 case LDT_ARRAY:
948 if (devinfo.target_id != INVALID_TARGET_ID)
949 hptiop_copy_info(pinfo, "[DISK %d_%d] ",
950 devinfo.vbus_id, devinfo.target_id);
951
952 capacity = le64_to_cpu(devinfo.capacity) * 512;
953 do_div(capacity, 1000000);
954 hptiop_copy_info(pinfo, "%s (%s), %lluMB, %s\n",
955 devinfo.u.array.name,
956 devinfo.u.array.array_type==AT_RAID0? "RAID0" :
957 devinfo.u.array.array_type==AT_RAID1? "RAID1" :
958 devinfo.u.array.array_type==AT_RAID5? "RAID5" :
959 devinfo.u.array.array_type==AT_RAID6? "RAID6" :
960 devinfo.u.array.array_type==AT_JBOD? "JBOD" :
961 "unknown",
962 capacity,
963 get_array_status(&devinfo));
964 for (i = 0; i < devinfo.u.array.ndisk; i++) {
965 if (hpt_id_valid(devinfo.u.array.members[i])) {
966 if (cpu_to_le16(1<<i) &
967 devinfo.u.array.critical_members)
968 hptiop_copy_info(pinfo, "\t*");
969 hptiop_dump_devinfo(hba, pinfo,
970 devinfo.u.array.members[i], indent+1);
971 }
972 else
973 hptiop_copy_info(pinfo, "\tMissing\n");
974 }
975 if (id == devinfo.u.array.transform_source) {
976 hptiop_copy_info(pinfo, "\tExpanding/Migrating to:\n");
977 hptiop_dump_devinfo(hba, pinfo,
978 devinfo.u.array.transform_target, indent+1);
979 }
980 break;
981 }
982}
983
984static ssize_t hptiop_show_version(struct class_device *class_dev, char *buf)
985{
986 return snprintf(buf, PAGE_SIZE, "%s\n", driver_ver);
987}
988
989static ssize_t hptiop_cdev_read(struct file *filp, char __user *buf,
990 size_t count, loff_t *ppos)
991{
992 struct hptiop_hba *hba = filp->private_data;
993 struct hptiop_getinfo info;
994 int i, j, ndev;
995 struct hpt_controller_info con_info;
996 struct hpt_channel_info chan_info;
997 __le32 ids[32];
998
999 info.buffer = buf;
1000 info.buflength = count;
1001 info.bufoffset = ppos ? *ppos : 0;
1002 info.filpos = 0;
1003 info.buffillen = 0;
1004
1005 if (hptiop_get_controller_info(hba, &con_info))
1006 return -EIO;
1007
1008 for (i = 0; i < con_info.num_buses; i++) {
1009 if (hptiop_get_channel_info(hba, i, &chan_info) == 0) {
1010 if (hpt_id_valid(chan_info.devices[0]))
1011 hptiop_dump_devinfo(hba, &info,
1012 chan_info.devices[0], 0);
1013 if (hpt_id_valid(chan_info.devices[1]))
1014 hptiop_dump_devinfo(hba, &info,
1015 chan_info.devices[1], 0);
1016 }
1017 }
1018
1019 ndev = hptiop_get_logical_devices(hba, ids,
1020 sizeof(ids) / sizeof(ids[0]));
1021
1022 /*
1023 * if hptiop_get_logical_devices fails, ndev==-1 and it just
1024 * output nothing here
1025 */
1026 for (j = 0; j < ndev; j++)
1027 hptiop_dump_devinfo(hba, &info, ids[j], 0);
1028
1029 if (ppos)
1030 *ppos += info.buffillen;
1031
1032 return info.buffillen;
1033}
1034
1035static int hptiop_cdev_ioctl(struct inode *inode, struct file *file,
1036 unsigned int cmd, unsigned long arg)
1037{
1038 struct hptiop_hba *hba = file->private_data;
1039 struct hpt_ioctl_u ioctl_u;
1040 struct hpt_ioctl_k ioctl_k;
1041 u32 bytes_returned;
1042 int err = -EINVAL;
1043
1044 if (copy_from_user(&ioctl_u,
1045 (void __user *)arg, sizeof(struct hpt_ioctl_u)))
1046 return -EINVAL;
1047
1048 if (ioctl_u.magic != HPT_IOCTL_MAGIC)
1049 return -EINVAL;
1050
1051 ioctl_k.ioctl_code = ioctl_u.ioctl_code;
1052 ioctl_k.inbuf = NULL;
1053 ioctl_k.inbuf_size = ioctl_u.inbuf_size;
1054 ioctl_k.outbuf = NULL;
1055 ioctl_k.outbuf_size = ioctl_u.outbuf_size;
1056 ioctl_k.hba = hba;
1057 ioctl_k.bytes_returned = &bytes_returned;
1058
1059 /* verify user buffer */
1060 if ((ioctl_k.inbuf_size && !access_ok(VERIFY_READ,
1061 ioctl_u.inbuf, ioctl_k.inbuf_size)) ||
1062 (ioctl_k.outbuf_size && !access_ok(VERIFY_WRITE,
1063 ioctl_u.outbuf, ioctl_k.outbuf_size)) ||
1064 (ioctl_u.bytes_returned && !access_ok(VERIFY_WRITE,
1065 ioctl_u.bytes_returned, sizeof(u32))) ||
1066 ioctl_k.inbuf_size + ioctl_k.outbuf_size > 0x10000) {
1067
1068 dprintk("scsi%d: got bad user address\n", hba->host->host_no);
1069 return -EINVAL;
1070 }
1071
1072 /* map buffer to kernel. */
1073 if (ioctl_k.inbuf_size) {
1074 ioctl_k.inbuf = kmalloc(ioctl_k.inbuf_size, GFP_KERNEL);
1075 if (!ioctl_k.inbuf) {
1076 dprintk("scsi%d: fail to alloc inbuf\n",
1077 hba->host->host_no);
1078 err = -ENOMEM;
1079 goto err_exit;
1080 }
1081
1082 if (copy_from_user(ioctl_k.inbuf,
1083 ioctl_u.inbuf, ioctl_k.inbuf_size)) {
1084 goto err_exit;
1085 }
1086 }
1087
1088 if (ioctl_k.outbuf_size) {
1089 ioctl_k.outbuf = kmalloc(ioctl_k.outbuf_size, GFP_KERNEL);
1090 if (!ioctl_k.outbuf) {
1091 dprintk("scsi%d: fail to alloc outbuf\n",
1092 hba->host->host_no);
1093 err = -ENOMEM;
1094 goto err_exit;
1095 }
1096 }
1097
1098 hptiop_do_ioctl(&ioctl_k);
1099
1100 if (ioctl_k.result == HPT_IOCTL_RESULT_OK) {
1101 if (ioctl_k.outbuf_size &&
1102 copy_to_user(ioctl_u.outbuf,
1103 ioctl_k.outbuf, ioctl_k.outbuf_size))
1104 goto err_exit;
1105
1106 if (ioctl_u.bytes_returned &&
1107 copy_to_user(ioctl_u.bytes_returned,
1108 &bytes_returned, sizeof(u32)))
1109 goto err_exit;
1110
1111 err = 0;
1112 }
1113
1114err_exit:
1115 kfree(ioctl_k.inbuf);
1116 kfree(ioctl_k.outbuf);
1117
1118 return err;
1119}
1120
1121static int hptiop_cdev_open(struct inode *inode, struct file *file)
1122{
1123 struct hptiop_hba *hba;
1124 unsigned i = 0, minor = iminor(inode);
1125 int ret = -ENODEV;
1126
1127 spin_lock(&hptiop_hba_list_lock);
1128 list_for_each_entry(hba, &hptiop_hba_list, link) {
1129 if (i == minor) {
1130 file->private_data = hba;
1131 ret = 0;
1132 goto out;
1133 }
1134 i++;
1135 }
1136
1137out:
1138 spin_unlock(&hptiop_hba_list_lock);
1139 return ret;
1140}
1141
1142static struct file_operations hptiop_cdev_fops = {
1143 .owner = THIS_MODULE,
1144 .read = hptiop_cdev_read,
1145 .ioctl = hptiop_cdev_ioctl,
1146 .open = hptiop_cdev_open,
1147};
1148
1149static ssize_t hptiop_show_fw_version(struct class_device *class_dev, char *buf)
1150{
1151 struct Scsi_Host *host = class_to_shost(class_dev);
1152 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
1153
1154 return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
1155 hba->firmware_version >> 24,
1156 (hba->firmware_version >> 16) & 0xff,
1157 (hba->firmware_version >> 8) & 0xff,
1158 hba->firmware_version & 0xff);
1159}
1160
1161static struct class_device_attribute hptiop_attr_version = {
1162 .attr = {
1163 .name = "driver-version",
1164 .mode = S_IRUGO,
1165 },
1166 .show = hptiop_show_version,
1167};
1168
1169static struct class_device_attribute hptiop_attr_fw_version = {
1170 .attr = {
1171 .name = "firmware-version",
1172 .mode = S_IRUGO,
1173 },
1174 .show = hptiop_show_fw_version,
1175};
1176
1177static struct class_device_attribute *hptiop_attrs[] = {
1178 &hptiop_attr_version,
1179 &hptiop_attr_fw_version,
1180 NULL
1181};
1182
1183static struct scsi_host_template driver_template = {
1184 .module = THIS_MODULE,
1185 .name = driver_name,
1186 .queuecommand = hptiop_queuecommand,
1187 .eh_device_reset_handler = hptiop_reset,
1188 .eh_bus_reset_handler = hptiop_reset,
1189 .info = hptiop_info,
1190 .unchecked_isa_dma = 0,
1191 .emulated = 0,
1192 .use_clustering = ENABLE_CLUSTERING,
1193 .proc_name = driver_name,
1194 .shost_attrs = hptiop_attrs,
1195 .this_id = -1,
1196 .change_queue_depth = hptiop_adjust_disk_queue_depth,
1197};
1198
1199static int __devinit hptiop_probe(struct pci_dev *pcidev,
1200 const struct pci_device_id *id)
1201{
1202 struct Scsi_Host *host = NULL;
1203 struct hptiop_hba *hba;
1204 struct hpt_iop_request_get_config iop_config;
1205 struct hpt_iop_request_set_config set_config;
1206 dma_addr_t start_phy;
1207 void *start_virt;
1208 u32 offset, i, req_size;
1209
1210 dprintk("hptiop_probe(%p)\n", pcidev);
1211
1212 if (pci_enable_device(pcidev)) {
1213 printk(KERN_ERR "hptiop: fail to enable pci device\n");
1214 return -ENODEV;
1215 }
1216
1217 printk(KERN_INFO "adapter at PCI %d:%d:%d, IRQ %d\n",
1218 pcidev->bus->number, pcidev->devfn >> 3, pcidev->devfn & 7,
1219 pcidev->irq);
1220
1221 pci_set_master(pcidev);
1222
1223 /* Enable 64bit DMA if possible */
1224 if (pci_set_dma_mask(pcidev, DMA_64BIT_MASK)) {
1225 if (pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
1226 printk(KERN_ERR "hptiop: fail to set dma_mask\n");
1227 goto disable_pci_device;
1228 }
1229 }
1230
1231 if (pci_request_regions(pcidev, driver_name)) {
1232 printk(KERN_ERR "hptiop: pci_request_regions failed\n");
1233 goto disable_pci_device;
1234 }
1235
1236 host = scsi_host_alloc(&driver_template, sizeof(struct hptiop_hba));
1237 if (!host) {
1238 printk(KERN_ERR "hptiop: fail to alloc scsi host\n");
1239 goto free_pci_regions;
1240 }
1241
1242 hba = (struct hptiop_hba *)host->hostdata;
1243
1244 hba->pcidev = pcidev;
1245 hba->host = host;
1246 hba->initialized = 0;
1247
1248 atomic_set(&hba->resetting, 0);
1249 atomic_set(&hba->reset_count, 0);
1250
1251 init_waitqueue_head(&hba->reset_wq);
1252 init_waitqueue_head(&hba->ioctl_wq);
1253
1254 host->max_lun = 1;
1255 host->max_channel = 0;
1256 host->io_port = 0;
1257 host->n_io_port = 0;
1258 host->irq = pcidev->irq;
1259
1260 if (hptiop_map_pci_bar(hba))
1261 goto free_scsi_host;
1262
1263 if (iop_wait_ready(hba->iop, 20000)) {
1264 printk(KERN_ERR "scsi%d: firmware not ready\n",
1265 hba->host->host_no);
1266 goto unmap_pci_bar;
1267 }
1268
1269 if (iop_get_config(hba, &iop_config)) {
1270 printk(KERN_ERR "scsi%d: get config failed\n",
1271 hba->host->host_no);
1272 goto unmap_pci_bar;
1273 }
1274
1275 hba->max_requests = min(le32_to_cpu(iop_config.max_requests),
1276 HPTIOP_MAX_REQUESTS);
1277 hba->max_devices = le32_to_cpu(iop_config.max_devices);
1278 hba->max_request_size = le32_to_cpu(iop_config.request_size);
1279 hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count);
1280 hba->firmware_version = le32_to_cpu(iop_config.firmware_version);
1281 hba->sdram_size = le32_to_cpu(iop_config.sdram_size);
1282
1283 host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9;
1284 host->max_id = le32_to_cpu(iop_config.max_devices);
1285 host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count);
1286 host->can_queue = le32_to_cpu(iop_config.max_requests);
1287 host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
1288 host->max_cmd_len = 16;
1289
1290 set_config.vbus_id = cpu_to_le32(host->host_no);
1291 set_config.iop_id = cpu_to_le32(host->host_no);
1292
1293 if (iop_set_config(hba, &set_config)) {
1294 printk(KERN_ERR "scsi%d: set config failed\n",
1295 hba->host->host_no);
1296 goto unmap_pci_bar;
1297 }
1298
1299 if (scsi_add_host(host, &pcidev->dev)) {
1300 printk(KERN_ERR "scsi%d: scsi_add_host failed\n",
1301 hba->host->host_no);
1302 goto unmap_pci_bar;
1303 }
1304
1305 pci_set_drvdata(pcidev, host);
1306
Thomas Gleixner1d6f3592006-07-01 19:29:42 -07001307 if (request_irq(pcidev->irq, hptiop_intr, IRQF_SHARED,
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +08001308 driver_name, hba)) {
1309 printk(KERN_ERR "scsi%d: request irq %d failed\n",
1310 hba->host->host_no, pcidev->irq);
1311 goto remove_scsi_host;
1312 }
1313
1314 /* Allocate request mem */
1315 req_size = sizeof(struct hpt_iop_request_scsi_command)
1316 + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1);
1317 if ((req_size& 0x1f) != 0)
1318 req_size = (req_size + 0x1f) & ~0x1f;
1319
1320 dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests);
1321
1322 hba->req_size = req_size;
1323 start_virt = dma_alloc_coherent(&pcidev->dev,
1324 hba->req_size*hba->max_requests + 0x20,
1325 &start_phy, GFP_KERNEL);
1326
1327 if (!start_virt) {
1328 printk(KERN_ERR "scsi%d: fail to alloc request mem\n",
1329 hba->host->host_no);
1330 goto free_request_irq;
1331 }
1332
1333 hba->dma_coherent = start_virt;
1334 hba->dma_coherent_handle = start_phy;
1335
1336 if ((start_phy & 0x1f) != 0)
1337 {
1338 offset = ((start_phy + 0x1f) & ~0x1f) - start_phy;
1339 start_phy += offset;
1340 start_virt += offset;
1341 }
1342
1343 hba->req_list = start_virt;
1344 for (i = 0; i < hba->max_requests; i++) {
1345 hba->reqs[i].next = NULL;
1346 hba->reqs[i].req_virt = start_virt;
1347 hba->reqs[i].req_shifted_phy = start_phy >> 5;
1348 hba->reqs[i].index = i;
1349 free_req(hba, &hba->reqs[i]);
1350 start_virt = (char *)start_virt + hba->req_size;
1351 start_phy = start_phy + hba->req_size;
1352 }
1353
1354 /* Enable Interrupt and start background task */
1355 if (hptiop_initialize_iop(hba))
1356 goto free_request_mem;
1357
1358 spin_lock(&hptiop_hba_list_lock);
1359 list_add_tail(&hba->link, &hptiop_hba_list);
1360 spin_unlock(&hptiop_hba_list_lock);
1361
1362 scsi_scan_host(host);
1363
1364 dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no);
1365 return 0;
1366
1367free_request_mem:
1368 dma_free_coherent(&hba->pcidev->dev,
1369 hba->req_size*hba->max_requests + 0x20,
1370 hba->dma_coherent, hba->dma_coherent_handle);
1371
1372free_request_irq:
1373 free_irq(hba->pcidev->irq, hba);
1374
1375remove_scsi_host:
1376 scsi_remove_host(host);
1377
1378unmap_pci_bar:
1379 iounmap(hba->iop);
1380
1381free_pci_regions:
1382 pci_release_regions(pcidev) ;
1383
1384free_scsi_host:
1385 scsi_host_put(host);
1386
1387disable_pci_device:
1388 pci_disable_device(pcidev);
1389
1390 dprintk("scsi%d: hptiop_probe fail\n", host->host_no);
1391 return -ENODEV;
1392}
1393
1394static void hptiop_shutdown(struct pci_dev *pcidev)
1395{
1396 struct Scsi_Host *host = pci_get_drvdata(pcidev);
1397 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
1398 struct hpt_iopmu __iomem *iop = hba->iop;
1399 u32 int_mask;
1400
1401 dprintk("hptiop_shutdown(%p)\n", hba);
1402
1403 /* stop the iop */
1404 if (iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_SHUTDOWN, 60000))
1405 printk(KERN_ERR "scsi%d: shutdown the iop timeout\n",
1406 hba->host->host_no);
1407
1408 /* disable all outbound interrupts */
1409 int_mask = readl(&iop->outbound_intmask);
1410 writel(int_mask |
1411 IOPMU_OUTBOUND_INT_MSG0 | IOPMU_OUTBOUND_INT_POSTQUEUE,
1412 &iop->outbound_intmask);
1413 hptiop_pci_posting_flush(iop);
1414}
1415
1416static void hptiop_remove(struct pci_dev *pcidev)
1417{
1418 struct Scsi_Host *host = pci_get_drvdata(pcidev);
1419 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
1420
1421 dprintk("scsi%d: hptiop_remove\n", hba->host->host_no);
1422
HighPoint Linux Team4f2ddba2006-06-14 16:50:57 +08001423 scsi_remove_host(host);
1424
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +08001425 spin_lock(&hptiop_hba_list_lock);
1426 list_del_init(&hba->link);
1427 spin_unlock(&hptiop_hba_list_lock);
1428
1429 hptiop_shutdown(pcidev);
1430
1431 free_irq(hba->pcidev->irq, hba);
1432
1433 dma_free_coherent(&hba->pcidev->dev,
1434 hba->req_size * hba->max_requests + 0x20,
1435 hba->dma_coherent,
1436 hba->dma_coherent_handle);
1437
1438 iounmap(hba->iop);
1439
1440 pci_release_regions(hba->pcidev);
1441 pci_set_drvdata(hba->pcidev, NULL);
1442 pci_disable_device(hba->pcidev);
1443
HighPoint Linux Teamede1e6f2006-05-16 14:38:09 +08001444 scsi_host_put(host);
1445}
1446
1447static struct pci_device_id hptiop_id_table[] = {
1448 { PCI_DEVICE(0x1103, 0x3220) },
1449 { PCI_DEVICE(0x1103, 0x3320) },
1450 {},
1451};
1452
1453MODULE_DEVICE_TABLE(pci, hptiop_id_table);
1454
1455static struct pci_driver hptiop_pci_driver = {
1456 .name = driver_name,
1457 .id_table = hptiop_id_table,
1458 .probe = hptiop_probe,
1459 .remove = hptiop_remove,
1460 .shutdown = hptiop_shutdown,
1461};
1462
1463static int __init hptiop_module_init(void)
1464{
1465 int error;
1466
1467 printk(KERN_INFO "%s %s\n", driver_name_long, driver_ver);
1468
1469 error = pci_register_driver(&hptiop_pci_driver);
1470 if (error < 0)
1471 return error;
1472
1473 hptiop_cdev_major = register_chrdev(0, "hptiop", &hptiop_cdev_fops);
1474 if (hptiop_cdev_major < 0) {
1475 printk(KERN_WARNING "unable to register hptiop device.\n");
1476 return hptiop_cdev_major;
1477 }
1478
1479 return 0;
1480}
1481
1482static void __exit hptiop_module_exit(void)
1483{
1484 dprintk("hptiop_module_exit\n");
1485 unregister_chrdev(hptiop_cdev_major, "hptiop");
1486 pci_unregister_driver(&hptiop_pci_driver);
1487}
1488
1489
1490module_init(hptiop_module_init);
1491module_exit(hptiop_module_exit);
1492
1493MODULE_LICENSE("GPL");