aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/scsi/hptiop.txt69
-rw-r--r--drivers/scsi/hptiop.c413
-rw-r--r--drivers/scsi/hptiop.h72
3 files changed, 530 insertions, 24 deletions
diff --git a/Documentation/scsi/hptiop.txt b/Documentation/scsi/hptiop.txt
index 9605179711f4..4a4f47e759cd 100644
--- a/Documentation/scsi/hptiop.txt
+++ b/Documentation/scsi/hptiop.txt
@@ -37,7 +37,7 @@ For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0:
37 0x40 Inbound Queue Port 37 0x40 Inbound Queue Port
38 0x44 Outbound Queue Port 38 0x44 Outbound Queue Port
39 39
40For Marvell IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1: 40For Marvell not Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
41 41
42 BAR0 offset Register 42 BAR0 offset Register
43 0x20400 Inbound Doorbell Register 43 0x20400 Inbound Doorbell Register
@@ -55,9 +55,31 @@ For Marvell IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
55 0x40-0x1040 Inbound Queue 55 0x40-0x1040 Inbound Queue
56 0x1040-0x2040 Outbound Queue 56 0x1040-0x2040 Outbound Queue
57 57
58For Marvell Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:
58 59
59I/O Request Workflow 60 BAR0 offset Register
60---------------------- 61 0x0 IOP configuration information.
62
63 BAR1 offset Register
64 0x4000 Inbound List Base Address Low
65 0x4004 Inbound List Base Address High
66 0x4018 Inbound List Write Pointer
67 0x402C Inbound List Configuration and Control
68 0x4050 Outbound List Base Address Low
69 0x4054 Outbound List Base Address High
70 0x4058 Outbound List Copy Pointer Shadow Base Address Low
71 0x405C Outbound List Copy Pointer Shadow Base Address High
72 0x4088 Outbound List Interrupt Cause
73 0x408C Outbound List Interrupt Enable
74 0x1020C PCIe Function 0 Interrupt Enable
75 0x10400 PCIe Function 0 to CPU Message A
76 0x10420 CPU to PCIe Function 0 Message A
77 0x10480 CPU to PCIe Function 0 Doorbell
78 0x10484 CPU to PCIe Function 0 Doorbell Enable
79
80
81I/O Request Workflow of Not Marvell Frey
82------------------------------------------
61 83
62All queued requests are handled via inbound/outbound queue port. 84All queued requests are handled via inbound/outbound queue port.
63A request packet can be allocated in either IOP or host memory. 85A request packet can be allocated in either IOP or host memory.
@@ -101,6 +123,45 @@ register 0. An outbound message with the same value indicates the completion
101of an inbound message. 123of an inbound message.
102 124
103 125
126I/O Request Workflow of Marvell Frey
127--------------------------------------
128
129All queued requests are handled via inbound/outbound list.
130
131To send a request to the controller:
132
133 - Allocate a free request in host DMA coherent memory.
134
135 Requests allocated in host memory must be aligned on 32-bytes boundary.
136
137 - Fill the request with index of the request in the flag.
138
139 Fill a free inbound list unit with the physical address and the size of
140 the request.
141
142 Set up the inbound list write pointer with the index of previous unit,
143 round to 0 if the index reaches the supported count of requests.
144
145 - Post the inbound list writer pointer to IOP.
146
147 - The IOP process the request. When the request is completed, the flag of
148 the request with or-ed IOPMU_QUEUE_MASK_HOST_BITS will be put into a
149 free outbound list unit and the index of the outbound list unit will be
150 put into the copy pointer shadow register. An outbound interrupt will be
151 generated.
152
153 - The host read the outbound list copy pointer shadow register and compare
154 with previous saved read ponter N. If they are different, the host will
155 read the (N+1)th outbound list unit.
156
157 The host get the index of the request from the (N+1)th outbound list
158 unit and complete the request.
159
160Non-queued requests (reset communication/reset/flush etc) can be sent via PCIe
161Function 0 to CPU Message A register. The CPU to PCIe Function 0 Message register
162with the same value indicates the completion of message.
163
164
104User-level Interface 165User-level Interface
105--------------------- 166---------------------
106 167
@@ -112,7 +173,7 @@ The driver exposes following sysfs attributes:
112 173
113 174
114----------------------------------------------------------------------------- 175-----------------------------------------------------------------------------
115Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved. 176Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved.
116 177
117 This file is distributed in the hope that it will be useful, 178 This file is distributed in the hope that it will be useful,
118 but WITHOUT ANY WARRANTY; without even the implied warranty of 179 but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 192724ed7a32..138e573f37ef 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * HighPoint RR3xxx/4xxx controller driver for Linux 2 * HighPoint RR3xxx/4xxx controller driver for Linux
3 * Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved. 3 * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx/4xxx Controller Driver");
42 42
43static char driver_name[] = "hptiop"; 43static char driver_name[] = "hptiop";
44static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller driver"; 44static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller driver";
45static const char driver_ver[] = "v1.6 (091225)"; 45static const char driver_ver[] = "v1.8";
46 46
47static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec); 47static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec);
48static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag, 48static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
@@ -77,6 +77,11 @@ static int iop_wait_ready_mv(struct hptiop_hba *hba, u32 millisec)
77 return iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_NOP, millisec); 77 return iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_NOP, millisec);
78} 78}
79 79
80static int iop_wait_ready_mvfrey(struct hptiop_hba *hba, u32 millisec)
81{
82 return iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_NOP, millisec);
83}
84
80static void hptiop_request_callback_itl(struct hptiop_hba *hba, u32 tag) 85static void hptiop_request_callback_itl(struct hptiop_hba *hba, u32 tag)
81{ 86{
82 if (tag & IOPMU_QUEUE_ADDR_HOST_BIT) 87 if (tag & IOPMU_QUEUE_ADDR_HOST_BIT)
@@ -230,6 +235,74 @@ static int iop_intr_mv(struct hptiop_hba *hba)
230 return ret; 235 return ret;
231} 236}
232 237
238static void hptiop_request_callback_mvfrey(struct hptiop_hba *hba, u32 _tag)
239{
240 u32 req_type = _tag & 0xf;
241 struct hpt_iop_request_scsi_command *req;
242
243 switch (req_type) {
244 case IOP_REQUEST_TYPE_GET_CONFIG:
245 case IOP_REQUEST_TYPE_SET_CONFIG:
246 hba->msg_done = 1;
247 break;
248
249 case IOP_REQUEST_TYPE_SCSI_COMMAND:
250 req = hba->reqs[(_tag >> 4) & 0xff].req_virt;
251 if (likely(_tag & IOPMU_QUEUE_REQUEST_RESULT_BIT))
252 req->header.result = IOP_RESULT_SUCCESS;
253 hptiop_finish_scsi_req(hba, (_tag >> 4) & 0xff, req);
254 break;
255
256 default:
257 break;
258 }
259}
260
261static int iop_intr_mvfrey(struct hptiop_hba *hba)
262{
263 u32 _tag, status, cptr, cur_rptr;
264 int ret = 0;
265
266 if (hba->initialized)
267 writel(0, &(hba->u.mvfrey.mu->pcie_f0_int_enable));
268
269 status = readl(&(hba->u.mvfrey.mu->f0_doorbell));
270 if (status) {
271 writel(status, &(hba->u.mvfrey.mu->f0_doorbell));
272 if (status & CPU_TO_F0_DRBL_MSG_BIT) {
273 u32 msg = readl(&(hba->u.mvfrey.mu->cpu_to_f0_msg_a));
274 dprintk("received outbound msg %x\n", msg);
275 hptiop_message_callback(hba, msg);
276 }
277 ret = 1;
278 }
279
280 status = readl(&(hba->u.mvfrey.mu->isr_cause));
281 if (status) {
282 writel(status, &(hba->u.mvfrey.mu->isr_cause));
283 do {
284 cptr = *hba->u.mvfrey.outlist_cptr & 0xff;
285 cur_rptr = hba->u.mvfrey.outlist_rptr;
286 while (cur_rptr != cptr) {
287 cur_rptr++;
288 if (cur_rptr == hba->u.mvfrey.list_count)
289 cur_rptr = 0;
290
291 _tag = hba->u.mvfrey.outlist[cur_rptr].val;
292 BUG_ON(!(_tag & IOPMU_QUEUE_MASK_HOST_BITS));
293 hptiop_request_callback_mvfrey(hba, _tag);
294 ret = 1;
295 }
296 hba->u.mvfrey.outlist_rptr = cur_rptr;
297 } while (cptr != (*hba->u.mvfrey.outlist_cptr & 0xff));
298 }
299
300 if (hba->initialized)
301 writel(0x1010, &(hba->u.mvfrey.mu->pcie_f0_int_enable));
302
303 return ret;
304}
305
233static int iop_send_sync_request_itl(struct hptiop_hba *hba, 306static int iop_send_sync_request_itl(struct hptiop_hba *hba,
234 void __iomem *_req, u32 millisec) 307 void __iomem *_req, u32 millisec)
235{ 308{
@@ -272,6 +345,26 @@ static int iop_send_sync_request_mv(struct hptiop_hba *hba,
272 return -1; 345 return -1;
273} 346}
274 347
348static int iop_send_sync_request_mvfrey(struct hptiop_hba *hba,
349 u32 size_bits, u32 millisec)
350{
351 struct hpt_iop_request_header *reqhdr =
352 hba->u.mvfrey.internal_req.req_virt;
353 u32 i;
354
355 hba->msg_done = 0;
356 reqhdr->flags |= cpu_to_le32(IOP_REQUEST_FLAG_SYNC_REQUEST);
357 hba->ops->post_req(hba, &(hba->u.mvfrey.internal_req));
358
359 for (i = 0; i < millisec; i++) {
360 iop_intr_mvfrey(hba);
361 if (hba->msg_done)
362 break;
363 msleep(1);
364 }
365 return hba->msg_done ? 0 : -1;
366}
367
275static void hptiop_post_msg_itl(struct hptiop_hba *hba, u32 msg) 368static void hptiop_post_msg_itl(struct hptiop_hba *hba, u32 msg)
276{ 369{
277 writel(msg, &hba->u.itl.iop->inbound_msgaddr0); 370 writel(msg, &hba->u.itl.iop->inbound_msgaddr0);
@@ -285,11 +378,18 @@ static void hptiop_post_msg_mv(struct hptiop_hba *hba, u32 msg)
285 readl(&hba->u.mv.regs->inbound_doorbell); 378 readl(&hba->u.mv.regs->inbound_doorbell);
286} 379}
287 380
381static void hptiop_post_msg_mvfrey(struct hptiop_hba *hba, u32 msg)
382{
383 writel(msg, &(hba->u.mvfrey.mu->f0_to_cpu_msg_a));
384 readl(&(hba->u.mvfrey.mu->f0_to_cpu_msg_a));
385}
386
288static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec) 387static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec)
289{ 388{
290 u32 i; 389 u32 i;
291 390
292 hba->msg_done = 0; 391 hba->msg_done = 0;
392 hba->ops->disable_intr(hba);
293 hba->ops->post_msg(hba, msg); 393 hba->ops->post_msg(hba, msg);
294 394
295 for (i = 0; i < millisec; i++) { 395 for (i = 0; i < millisec; i++) {
@@ -301,6 +401,7 @@ static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec)
301 msleep(1); 401 msleep(1);
302 } 402 }
303 403
404 hba->ops->enable_intr(hba);
304 return hba->msg_done? 0 : -1; 405 return hba->msg_done? 0 : -1;
305} 406}
306 407
@@ -354,6 +455,28 @@ static int iop_get_config_mv(struct hptiop_hba *hba,
354 return 0; 455 return 0;
355} 456}
356 457
458static int iop_get_config_mvfrey(struct hptiop_hba *hba,
459 struct hpt_iop_request_get_config *config)
460{
461 struct hpt_iop_request_get_config *info = hba->u.mvfrey.config;
462
463 if (info->header.size != sizeof(struct hpt_iop_request_get_config) ||
464 info->header.type != IOP_REQUEST_TYPE_GET_CONFIG)
465 return -1;
466
467 config->interface_version = info->interface_version;
468 config->firmware_version = info->firmware_version;
469 config->max_requests = info->max_requests;
470 config->request_size = info->request_size;
471 config->max_sg_count = info->max_sg_count;
472 config->data_transfer_length = info->data_transfer_length;
473 config->alignment_mask = info->alignment_mask;
474 config->max_devices = info->max_devices;
475 config->sdram_size = info->sdram_size;
476
477 return 0;
478}
479
357static int iop_set_config_itl(struct hptiop_hba *hba, 480static int iop_set_config_itl(struct hptiop_hba *hba,
358 struct hpt_iop_request_set_config *config) 481 struct hpt_iop_request_set_config *config)
359{ 482{
@@ -408,6 +531,29 @@ static int iop_set_config_mv(struct hptiop_hba *hba,
408 return 0; 531 return 0;
409} 532}
410 533
534static int iop_set_config_mvfrey(struct hptiop_hba *hba,
535 struct hpt_iop_request_set_config *config)
536{
537 struct hpt_iop_request_set_config *req =
538 hba->u.mvfrey.internal_req.req_virt;
539
540 memcpy(req, config, sizeof(struct hpt_iop_request_set_config));
541 req->header.flags = cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT);
542 req->header.type = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG);
543 req->header.size =
544 cpu_to_le32(sizeof(struct hpt_iop_request_set_config));
545 req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
546 req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG<<5);
547 req->header.context_hi32 = 0;
548
549 if (iop_send_sync_request_mvfrey(hba, 0, 20000)) {
550 dprintk("Set config send cmd failed\n");
551 return -1;
552 }
553
554 return 0;
555}
556
411static void hptiop_enable_intr_itl(struct hptiop_hba *hba) 557static void hptiop_enable_intr_itl(struct hptiop_hba *hba)
412{ 558{
413 writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0), 559 writel(~(IOPMU_OUTBOUND_INT_POSTQUEUE | IOPMU_OUTBOUND_INT_MSG0),
@@ -420,6 +566,13 @@ static void hptiop_enable_intr_mv(struct hptiop_hba *hba)
420 &hba->u.mv.regs->outbound_intmask); 566 &hba->u.mv.regs->outbound_intmask);
421} 567}
422 568
569static void hptiop_enable_intr_mvfrey(struct hptiop_hba *hba)
570{
571 writel(CPU_TO_F0_DRBL_MSG_BIT, &(hba->u.mvfrey.mu->f0_doorbell_enable));
572 writel(0x1, &(hba->u.mvfrey.mu->isr_enable));
573 writel(0x1010, &(hba->u.mvfrey.mu->pcie_f0_int_enable));
574}
575
423static int hptiop_initialize_iop(struct hptiop_hba *hba) 576static int hptiop_initialize_iop(struct hptiop_hba *hba)
424{ 577{
425 /* enable interrupts */ 578 /* enable interrupts */
@@ -502,17 +655,39 @@ static int hptiop_map_pci_bar_mv(struct hptiop_hba *hba)
502 return 0; 655 return 0;
503} 656}
504 657
658static int hptiop_map_pci_bar_mvfrey(struct hptiop_hba *hba)
659{
660 hba->u.mvfrey.config = hptiop_map_pci_bar(hba, 0);
661 if (hba->u.mvfrey.config == NULL)
662 return -1;
663
664 hba->u.mvfrey.mu = hptiop_map_pci_bar(hba, 2);
665 if (hba->u.mvfrey.mu == NULL) {
666 iounmap(hba->u.mvfrey.config);
667 return -1;
668 }
669
670 return 0;
671}
672
505static void hptiop_unmap_pci_bar_mv(struct hptiop_hba *hba) 673static void hptiop_unmap_pci_bar_mv(struct hptiop_hba *hba)
506{ 674{
507 iounmap(hba->u.mv.regs); 675 iounmap(hba->u.mv.regs);
508 iounmap(hba->u.mv.mu); 676 iounmap(hba->u.mv.mu);
509} 677}
510 678
679static void hptiop_unmap_pci_bar_mvfrey(struct hptiop_hba *hba)
680{
681 iounmap(hba->u.mvfrey.config);
682 iounmap(hba->u.mvfrey.mu);
683}
684
511static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg) 685static void hptiop_message_callback(struct hptiop_hba *hba, u32 msg)
512{ 686{
513 dprintk("iop message 0x%x\n", msg); 687 dprintk("iop message 0x%x\n", msg);
514 688
515 if (msg == IOPMU_INBOUND_MSG0_NOP) 689 if (msg == IOPMU_INBOUND_MSG0_NOP ||
690 msg == IOPMU_INBOUND_MSG0_RESET_COMM)
516 hba->msg_done = 1; 691 hba->msg_done = 1;
517 692
518 if (!hba->initialized) 693 if (!hba->initialized)
@@ -592,6 +767,7 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
592 memcpy(scp->sense_buffer, &req->sg_list, 767 memcpy(scp->sense_buffer, &req->sg_list,
593 min_t(size_t, SCSI_SENSE_BUFFERSIZE, 768 min_t(size_t, SCSI_SENSE_BUFFERSIZE,
594 le32_to_cpu(req->dataxfer_length))); 769 le32_to_cpu(req->dataxfer_length)));
770 goto skip_resid;
595 break; 771 break;
596 772
597 default: 773 default:
@@ -599,6 +775,10 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
599 break; 775 break;
600 } 776 }
601 777
778 scsi_set_resid(scp,
779 scsi_bufflen(scp) - le32_to_cpu(req->dataxfer_length));
780
781skip_resid:
602 dprintk("scsi_done(%p)\n", scp); 782 dprintk("scsi_done(%p)\n", scp);
603 scp->scsi_done(scp); 783 scp->scsi_done(scp);
604 free_req(hba, &hba->reqs[tag]); 784 free_req(hba, &hba->reqs[tag]);
@@ -692,7 +872,8 @@ static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg)
692 BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors); 872 BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors);
693 873
694 scsi_for_each_sg(scp, sg, HPT_SCP(scp)->sgcnt, idx) { 874 scsi_for_each_sg(scp, sg, HPT_SCP(scp)->sgcnt, idx) {
695 psg[idx].pci_address = cpu_to_le64(sg_dma_address(sg)); 875 psg[idx].pci_address = cpu_to_le64(sg_dma_address(sg)) |
876 hba->ops->host_phy_flag;
696 psg[idx].size = cpu_to_le32(sg_dma_len(sg)); 877 psg[idx].size = cpu_to_le32(sg_dma_len(sg));
697 psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ? 878 psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ?
698 cpu_to_le32(1) : 0; 879 cpu_to_le32(1) : 0;
@@ -751,6 +932,78 @@ static void hptiop_post_req_mv(struct hptiop_hba *hba,
751 MVIOP_MU_QUEUE_ADDR_HOST_BIT | size_bit, hba); 932 MVIOP_MU_QUEUE_ADDR_HOST_BIT | size_bit, hba);
752} 933}
753 934
935static void hptiop_post_req_mvfrey(struct hptiop_hba *hba,
936 struct hptiop_request *_req)
937{
938 struct hpt_iop_request_header *reqhdr = _req->req_virt;
939 u32 index;
940
941 reqhdr->flags |= cpu_to_le32(IOP_REQUEST_FLAG_OUTPUT_CONTEXT |
942 IOP_REQUEST_FLAG_ADDR_BITS |
943 ((_req->req_shifted_phy >> 11) & 0xffff0000));
944 reqhdr->context = cpu_to_le32(IOPMU_QUEUE_ADDR_HOST_BIT |
945 (_req->index << 4) | reqhdr->type);
946 reqhdr->context_hi32 = cpu_to_le32((_req->req_shifted_phy << 5) &
947 0xffffffff);
948
949 hba->u.mvfrey.inlist_wptr++;
950 index = hba->u.mvfrey.inlist_wptr & 0x3fff;
951
952 if (index == hba->u.mvfrey.list_count) {
953 index = 0;
954 hba->u.mvfrey.inlist_wptr &= ~0x3fff;
955 hba->u.mvfrey.inlist_wptr ^= CL_POINTER_TOGGLE;
956 }
957
958 hba->u.mvfrey.inlist[index].addr =
959 (dma_addr_t)_req->req_shifted_phy << 5;
960 hba->u.mvfrey.inlist[index].intrfc_len = (reqhdr->size + 3) / 4;
961 writel(hba->u.mvfrey.inlist_wptr,
962 &(hba->u.mvfrey.mu->inbound_write_ptr));
963 readl(&(hba->u.mvfrey.mu->inbound_write_ptr));
964}
965
966static int hptiop_reset_comm_itl(struct hptiop_hba *hba)
967{
968 return 0;
969}
970
971static int hptiop_reset_comm_mv(struct hptiop_hba *hba)
972{
973 return 0;
974}
975
976static int hptiop_reset_comm_mvfrey(struct hptiop_hba *hba)
977{
978 u32 list_count = hba->u.mvfrey.list_count;
979
980 if (iop_send_sync_msg(hba, IOPMU_INBOUND_MSG0_RESET_COMM, 3000))
981 return -1;
982
983 /* wait 100ms for MCU ready */
984 msleep(100);
985
986 writel(cpu_to_le32(hba->u.mvfrey.inlist_phy & 0xffffffff),
987 &(hba->u.mvfrey.mu->inbound_base));
988 writel(cpu_to_le32((hba->u.mvfrey.inlist_phy >> 16) >> 16),
989 &(hba->u.mvfrey.mu->inbound_base_high));
990
991 writel(cpu_to_le32(hba->u.mvfrey.outlist_phy & 0xffffffff),
992 &(hba->u.mvfrey.mu->outbound_base));
993 writel(cpu_to_le32((hba->u.mvfrey.outlist_phy >> 16) >> 16),
994 &(hba->u.mvfrey.mu->outbound_base_high));
995
996 writel(cpu_to_le32(hba->u.mvfrey.outlist_cptr_phy & 0xffffffff),
997 &(hba->u.mvfrey.mu->outbound_shadow_base));
998 writel(cpu_to_le32((hba->u.mvfrey.outlist_cptr_phy >> 16) >> 16),
999 &(hba->u.mvfrey.mu->outbound_shadow_base_high));
1000
1001 hba->u.mvfrey.inlist_wptr = (list_count - 1) | CL_POINTER_TOGGLE;
1002 *hba->u.mvfrey.outlist_cptr = (list_count - 1) | CL_POINTER_TOGGLE;
1003 hba->u.mvfrey.outlist_rptr = list_count - 1;
1004 return 0;
1005}
1006
754static int hptiop_queuecommand_lck(struct scsi_cmnd *scp, 1007static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
755 void (*done)(struct scsi_cmnd *)) 1008 void (*done)(struct scsi_cmnd *))
756{ 1009{
@@ -771,14 +1024,15 @@ static int hptiop_queuecommand_lck(struct scsi_cmnd *scp,
771 1024
772 _req->scp = scp; 1025 _req->scp = scp;
773 1026
774 dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%x-%x-%x) " 1027 dprintk("hptiop_queuecmd(scp=%p) %d/%d/%d/%d cdb=(%08x-%08x-%08x-%08x) "
775 "req_index=%d, req=%p\n", 1028 "req_index=%d, req=%p\n",
776 scp, 1029 scp,
777 host->host_no, scp->device->channel, 1030 host->host_no, scp->device->channel,
778 scp->device->id, scp->device->lun, 1031 scp->device->id, scp->device->lun,
779 ((u32 *)scp->cmnd)[0], 1032 cpu_to_be32(((u32 *)scp->cmnd)[0]),
780 ((u32 *)scp->cmnd)[1], 1033 cpu_to_be32(((u32 *)scp->cmnd)[1]),
781 ((u32 *)scp->cmnd)[2], 1034 cpu_to_be32(((u32 *)scp->cmnd)[2]),
1035 cpu_to_be32(((u32 *)scp->cmnd)[3]),
782 _req->index, _req->req_virt); 1036 _req->index, _req->req_virt);
783 1037
784 scp->result = 0; 1038 scp->result = 0;
@@ -933,6 +1187,11 @@ static struct scsi_host_template driver_template = {
933 .change_queue_depth = hptiop_adjust_disk_queue_depth, 1187 .change_queue_depth = hptiop_adjust_disk_queue_depth,
934}; 1188};
935 1189
1190static int hptiop_internal_memalloc_itl(struct hptiop_hba *hba)
1191{
1192 return 0;
1193}
1194
936static int hptiop_internal_memalloc_mv(struct hptiop_hba *hba) 1195static int hptiop_internal_memalloc_mv(struct hptiop_hba *hba)
937{ 1196{
938 hba->u.mv.internal_req = dma_alloc_coherent(&hba->pcidev->dev, 1197 hba->u.mv.internal_req = dma_alloc_coherent(&hba->pcidev->dev,
@@ -943,6 +1202,63 @@ static int hptiop_internal_memalloc_mv(struct hptiop_hba *hba)
943 return -1; 1202 return -1;
944} 1203}
945 1204
1205static int hptiop_internal_memalloc_mvfrey(struct hptiop_hba *hba)
1206{
1207 u32 list_count = readl(&hba->u.mvfrey.mu->inbound_conf_ctl);
1208 char *p;
1209 dma_addr_t phy;
1210
1211 BUG_ON(hba->max_request_size == 0);
1212
1213 if (list_count == 0) {
1214 BUG_ON(1);
1215 return -1;
1216 }
1217
1218 list_count >>= 16;
1219
1220 hba->u.mvfrey.list_count = list_count;
1221 hba->u.mvfrey.internal_mem_size = 0x800 +
1222 list_count * sizeof(struct mvfrey_inlist_entry) +
1223 list_count * sizeof(struct mvfrey_outlist_entry) +
1224 sizeof(int);
1225
1226 p = dma_alloc_coherent(&hba->pcidev->dev,
1227 hba->u.mvfrey.internal_mem_size, &phy, GFP_KERNEL);
1228 if (!p)
1229 return -1;
1230
1231 hba->u.mvfrey.internal_req.req_virt = p;
1232 hba->u.mvfrey.internal_req.req_shifted_phy = phy >> 5;
1233 hba->u.mvfrey.internal_req.scp = NULL;
1234 hba->u.mvfrey.internal_req.next = NULL;
1235
1236 p += 0x800;
1237 phy += 0x800;
1238
1239 hba->u.mvfrey.inlist = (struct mvfrey_inlist_entry *)p;
1240 hba->u.mvfrey.inlist_phy = phy;
1241
1242 p += list_count * sizeof(struct mvfrey_inlist_entry);
1243 phy += list_count * sizeof(struct mvfrey_inlist_entry);
1244
1245 hba->u.mvfrey.outlist = (struct mvfrey_outlist_entry *)p;
1246 hba->u.mvfrey.outlist_phy = phy;
1247
1248 p += list_count * sizeof(struct mvfrey_outlist_entry);
1249 phy += list_count * sizeof(struct mvfrey_outlist_entry);
1250
1251 hba->u.mvfrey.outlist_cptr = (__le32 *)p;
1252 hba->u.mvfrey.outlist_cptr_phy = phy;
1253
1254 return 0;
1255}
1256
1257static int hptiop_internal_memfree_itl(struct hptiop_hba *hba)
1258{
1259 return 0;
1260}
1261
946static int hptiop_internal_memfree_mv(struct hptiop_hba *hba) 1262static int hptiop_internal_memfree_mv(struct hptiop_hba *hba)
947{ 1263{
948 if (hba->u.mv.internal_req) { 1264 if (hba->u.mv.internal_req) {
@@ -953,6 +1269,19 @@ static int hptiop_internal_memfree_mv(struct hptiop_hba *hba)
953 return -1; 1269 return -1;
954} 1270}
955 1271
1272static int hptiop_internal_memfree_mvfrey(struct hptiop_hba *hba)
1273{
1274 if (hba->u.mvfrey.internal_req.req_virt) {
1275 dma_free_coherent(&hba->pcidev->dev,
1276 hba->u.mvfrey.internal_mem_size,
1277 hba->u.mvfrey.internal_req.req_virt,
1278 (dma_addr_t)
1279 hba->u.mvfrey.internal_req.req_shifted_phy << 5);
1280 return 0;
1281 } else
1282 return -1;
1283}
1284
956static int __devinit hptiop_probe(struct pci_dev *pcidev, 1285static int __devinit hptiop_probe(struct pci_dev *pcidev,
957 const struct pci_device_id *id) 1286 const struct pci_device_id *id)
958{ 1287{
@@ -1027,7 +1356,7 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
1027 goto unmap_pci_bar; 1356 goto unmap_pci_bar;
1028 } 1357 }
1029 1358
1030 if (hba->ops->internal_memalloc) { 1359 if (hba->ops->family == MV_BASED_IOP) {
1031 if (hba->ops->internal_memalloc(hba)) { 1360 if (hba->ops->internal_memalloc(hba)) {
1032 printk(KERN_ERR "scsi%d: internal_memalloc failed\n", 1361 printk(KERN_ERR "scsi%d: internal_memalloc failed\n",
1033 hba->host->host_no); 1362 hba->host->host_no);
@@ -1050,6 +1379,19 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
1050 hba->interface_version = le32_to_cpu(iop_config.interface_version); 1379 hba->interface_version = le32_to_cpu(iop_config.interface_version);
1051 hba->sdram_size = le32_to_cpu(iop_config.sdram_size); 1380 hba->sdram_size = le32_to_cpu(iop_config.sdram_size);
1052 1381
1382 if (hba->ops->family == MVFREY_BASED_IOP) {
1383 if (hba->ops->internal_memalloc(hba)) {
1384 printk(KERN_ERR "scsi%d: internal_memalloc failed\n",
1385 hba->host->host_no);
1386 goto unmap_pci_bar;
1387 }
1388 if (hba->ops->reset_comm(hba)) {
1389 printk(KERN_ERR "scsi%d: reset comm failed\n",
1390 hba->host->host_no);
1391 goto unmap_pci_bar;
1392 }
1393 }
1394
1053 if (hba->firmware_version > 0x01020000 || 1395 if (hba->firmware_version > 0x01020000 ||
1054 hba->interface_version > 0x01020000) 1396 hba->interface_version > 0x01020000)
1055 hba->iopintf_v2 = 1; 1397 hba->iopintf_v2 = 1;
@@ -1104,14 +1446,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
1104 hba->dma_coherent = start_virt; 1446 hba->dma_coherent = start_virt;
1105 hba->dma_coherent_handle = start_phy; 1447 hba->dma_coherent_handle = start_phy;
1106 1448
1107 if ((start_phy & 0x1f) != 0) 1449 if ((start_phy & 0x1f) != 0) {
1108 {
1109 offset = ((start_phy + 0x1f) & ~0x1f) - start_phy; 1450 offset = ((start_phy + 0x1f) & ~0x1f) - start_phy;
1110 start_phy += offset; 1451 start_phy += offset;
1111 start_virt += offset; 1452 start_virt += offset;
1112 } 1453 }
1113 1454
1114 hba->req_list = start_virt; 1455 hba->req_list = NULL;
1115 for (i = 0; i < hba->max_requests; i++) { 1456 for (i = 0; i < hba->max_requests; i++) {
1116 hba->reqs[i].next = NULL; 1457 hba->reqs[i].next = NULL;
1117 hba->reqs[i].req_virt = start_virt; 1458 hba->reqs[i].req_virt = start_virt;
@@ -1132,7 +1473,6 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev,
1132 goto free_request_mem; 1473 goto free_request_mem;
1133 } 1474 }
1134 1475
1135
1136 scsi_scan_host(host); 1476 scsi_scan_host(host);
1137 1477
1138 dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no); 1478 dprintk("scsi%d: hptiop_probe successfully\n", hba->host->host_no);
@@ -1147,8 +1487,7 @@ free_request_irq:
1147 free_irq(hba->pcidev->irq, hba); 1487 free_irq(hba->pcidev->irq, hba);
1148 1488
1149unmap_pci_bar: 1489unmap_pci_bar:
1150 if (hba->ops->internal_memfree) 1490 hba->ops->internal_memfree(hba);
1151 hba->ops->internal_memfree(hba);
1152 1491
1153 hba->ops->unmap_pci_bar(hba); 1492 hba->ops->unmap_pci_bar(hba);
1154 1493
@@ -1198,6 +1537,16 @@ static void hptiop_disable_intr_mv(struct hptiop_hba *hba)
1198 readl(&hba->u.mv.regs->outbound_intmask); 1537 readl(&hba->u.mv.regs->outbound_intmask);
1199} 1538}
1200 1539
1540static void hptiop_disable_intr_mvfrey(struct hptiop_hba *hba)
1541{
1542 writel(0, &(hba->u.mvfrey.mu->f0_doorbell_enable));
1543 readl(&(hba->u.mvfrey.mu->f0_doorbell_enable));
1544 writel(0, &(hba->u.mvfrey.mu->isr_enable));
1545 readl(&(hba->u.mvfrey.mu->isr_enable));
1546 writel(0, &(hba->u.mvfrey.mu->pcie_f0_int_enable));
1547 readl(&(hba->u.mvfrey.mu->pcie_f0_int_enable));
1548}
1549
1201static void hptiop_remove(struct pci_dev *pcidev) 1550static void hptiop_remove(struct pci_dev *pcidev)
1202{ 1551{
1203 struct Scsi_Host *host = pci_get_drvdata(pcidev); 1552 struct Scsi_Host *host = pci_get_drvdata(pcidev);
@@ -1216,8 +1565,7 @@ static void hptiop_remove(struct pci_dev *pcidev)
1216 hba->dma_coherent, 1565 hba->dma_coherent,
1217 hba->dma_coherent_handle); 1566 hba->dma_coherent_handle);
1218 1567
1219 if (hba->ops->internal_memfree) 1568 hba->ops->internal_memfree(hba);
1220 hba->ops->internal_memfree(hba);
1221 1569
1222 hba->ops->unmap_pci_bar(hba); 1570 hba->ops->unmap_pci_bar(hba);
1223 1571
@@ -1229,9 +1577,10 @@ static void hptiop_remove(struct pci_dev *pcidev)
1229} 1577}
1230 1578
1231static struct hptiop_adapter_ops hptiop_itl_ops = { 1579static struct hptiop_adapter_ops hptiop_itl_ops = {
1580 .family = INTEL_BASED_IOP,
1232 .iop_wait_ready = iop_wait_ready_itl, 1581 .iop_wait_ready = iop_wait_ready_itl,
1233 .internal_memalloc = NULL, 1582 .internal_memalloc = hptiop_internal_memalloc_itl,
1234 .internal_memfree = NULL, 1583 .internal_memfree = hptiop_internal_memfree_itl,
1235 .map_pci_bar = hptiop_map_pci_bar_itl, 1584 .map_pci_bar = hptiop_map_pci_bar_itl,
1236 .unmap_pci_bar = hptiop_unmap_pci_bar_itl, 1585 .unmap_pci_bar = hptiop_unmap_pci_bar_itl,
1237 .enable_intr = hptiop_enable_intr_itl, 1586 .enable_intr = hptiop_enable_intr_itl,
@@ -1242,9 +1591,12 @@ static struct hptiop_adapter_ops hptiop_itl_ops = {
1242 .post_msg = hptiop_post_msg_itl, 1591 .post_msg = hptiop_post_msg_itl,
1243 .post_req = hptiop_post_req_itl, 1592 .post_req = hptiop_post_req_itl,
1244 .hw_dma_bit_mask = 64, 1593 .hw_dma_bit_mask = 64,
1594 .reset_comm = hptiop_reset_comm_itl,
1595 .host_phy_flag = cpu_to_le64(0),
1245}; 1596};
1246 1597
1247static struct hptiop_adapter_ops hptiop_mv_ops = { 1598static struct hptiop_adapter_ops hptiop_mv_ops = {
1599 .family = MV_BASED_IOP,
1248 .iop_wait_ready = iop_wait_ready_mv, 1600 .iop_wait_ready = iop_wait_ready_mv,
1249 .internal_memalloc = hptiop_internal_memalloc_mv, 1601 .internal_memalloc = hptiop_internal_memalloc_mv,
1250 .internal_memfree = hptiop_internal_memfree_mv, 1602 .internal_memfree = hptiop_internal_memfree_mv,
@@ -1258,6 +1610,27 @@ static struct hptiop_adapter_ops hptiop_mv_ops = {
1258 .post_msg = hptiop_post_msg_mv, 1610 .post_msg = hptiop_post_msg_mv,
1259 .post_req = hptiop_post_req_mv, 1611 .post_req = hptiop_post_req_mv,
1260 .hw_dma_bit_mask = 33, 1612 .hw_dma_bit_mask = 33,
1613 .reset_comm = hptiop_reset_comm_mv,
1614 .host_phy_flag = cpu_to_le64(0),
1615};
1616
1617static struct hptiop_adapter_ops hptiop_mvfrey_ops = {
1618 .family = MVFREY_BASED_IOP,
1619 .iop_wait_ready = iop_wait_ready_mvfrey,
1620 .internal_memalloc = hptiop_internal_memalloc_mvfrey,
1621 .internal_memfree = hptiop_internal_memfree_mvfrey,
1622 .map_pci_bar = hptiop_map_pci_bar_mvfrey,
1623 .unmap_pci_bar = hptiop_unmap_pci_bar_mvfrey,
1624 .enable_intr = hptiop_enable_intr_mvfrey,
1625 .disable_intr = hptiop_disable_intr_mvfrey,
1626 .get_config = iop_get_config_mvfrey,
1627 .set_config = iop_set_config_mvfrey,
1628 .iop_intr = iop_intr_mvfrey,
1629 .post_msg = hptiop_post_msg_mvfrey,
1630 .post_req = hptiop_post_req_mvfrey,
1631 .hw_dma_bit_mask = 64,
1632 .reset_comm = hptiop_reset_comm_mvfrey,
1633 .host_phy_flag = cpu_to_le64(1),
1261}; 1634};
1262 1635
1263static struct pci_device_id hptiop_id_table[] = { 1636static struct pci_device_id hptiop_id_table[] = {
@@ -1283,6 +1656,8 @@ static struct pci_device_id hptiop_id_table[] = {
1283 { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops }, 1656 { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops },
1284 { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops }, 1657 { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops },
1285 { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops }, 1658 { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops },
1659 { PCI_VDEVICE(TTI, 0x4520), (kernel_ulong_t)&hptiop_mvfrey_ops },
1660 { PCI_VDEVICE(TTI, 0x4522), (kernel_ulong_t)&hptiop_mvfrey_ops },
1286 {}, 1661 {},
1287}; 1662};
1288 1663
diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h
index baa648d87fde..020619d60b08 100644
--- a/drivers/scsi/hptiop.h
+++ b/drivers/scsi/hptiop.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * HighPoint RR3xxx/4xxx controller driver for Linux 2 * HighPoint RR3xxx/4xxx controller driver for Linux
3 * Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved. 3 * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License as published by
@@ -75,6 +75,45 @@ struct hpt_iopmv_regs {
75 __le32 outbound_intmask; 75 __le32 outbound_intmask;
76}; 76};
77 77
78#pragma pack(1)
79struct hpt_iopmu_mvfrey {
80 __le32 reserved0[(0x4000 - 0) / 4];
81 __le32 inbound_base;
82 __le32 inbound_base_high;
83 __le32 reserved1[(0x4018 - 0x4008) / 4];
84 __le32 inbound_write_ptr;
85 __le32 reserved2[(0x402c - 0x401c) / 4];
86 __le32 inbound_conf_ctl;
87 __le32 reserved3[(0x4050 - 0x4030) / 4];
88 __le32 outbound_base;
89 __le32 outbound_base_high;
90 __le32 outbound_shadow_base;
91 __le32 outbound_shadow_base_high;
92 __le32 reserved4[(0x4088 - 0x4060) / 4];
93 __le32 isr_cause;
94 __le32 isr_enable;
95 __le32 reserved5[(0x1020c - 0x4090) / 4];
96 __le32 pcie_f0_int_enable;
97 __le32 reserved6[(0x10400 - 0x10210) / 4];
98 __le32 f0_to_cpu_msg_a;
99 __le32 reserved7[(0x10420 - 0x10404) / 4];
100 __le32 cpu_to_f0_msg_a;
101 __le32 reserved8[(0x10480 - 0x10424) / 4];
102 __le32 f0_doorbell;
103 __le32 f0_doorbell_enable;
104};
105
106struct mvfrey_inlist_entry {
107 dma_addr_t addr;
108 __le32 intrfc_len;
109 __le32 reserved;
110};
111
112struct mvfrey_outlist_entry {
113 __le32 val;
114};
115#pragma pack()
116
78#define MVIOP_MU_QUEUE_ADDR_HOST_MASK (~(0x1full)) 117#define MVIOP_MU_QUEUE_ADDR_HOST_MASK (~(0x1full))
79#define MVIOP_MU_QUEUE_ADDR_HOST_BIT 4 118#define MVIOP_MU_QUEUE_ADDR_HOST_BIT 4
80 119
@@ -87,6 +126,9 @@ struct hpt_iopmv_regs {
87#define MVIOP_MU_OUTBOUND_INT_MSG 1 126#define MVIOP_MU_OUTBOUND_INT_MSG 1
88#define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2 127#define MVIOP_MU_OUTBOUND_INT_POSTQUEUE 2
89 128
129#define CL_POINTER_TOGGLE 0x00004000
130#define CPU_TO_F0_DRBL_MSG_BIT 0x02000000
131
90enum hpt_iopmu_message { 132enum hpt_iopmu_message {
91 /* host-to-iop messages */ 133 /* host-to-iop messages */
92 IOPMU_INBOUND_MSG0_NOP = 0, 134 IOPMU_INBOUND_MSG0_NOP = 0,
@@ -95,6 +137,7 @@ enum hpt_iopmu_message {
95 IOPMU_INBOUND_MSG0_SHUTDOWN, 137 IOPMU_INBOUND_MSG0_SHUTDOWN,
96 IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK, 138 IOPMU_INBOUND_MSG0_STOP_BACKGROUND_TASK,
97 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK, 139 IOPMU_INBOUND_MSG0_START_BACKGROUND_TASK,
140 IOPMU_INBOUND_MSG0_RESET_COMM,
98 IOPMU_INBOUND_MSG0_MAX = 0xff, 141 IOPMU_INBOUND_MSG0_MAX = 0xff,
99 /* iop-to-host messages */ 142 /* iop-to-host messages */
100 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100, 143 IOPMU_OUTBOUND_MSG0_REGISTER_DEVICE_0 = 0x100,
@@ -118,6 +161,7 @@ struct hpt_iop_request_header {
118#define IOP_REQUEST_FLAG_BIST_REQUEST 2 161#define IOP_REQUEST_FLAG_BIST_REQUEST 2
119#define IOP_REQUEST_FLAG_REMAPPED 4 162#define IOP_REQUEST_FLAG_REMAPPED 4
120#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8 163#define IOP_REQUEST_FLAG_OUTPUT_CONTEXT 8
164#define IOP_REQUEST_FLAG_ADDR_BITS 0x40 /* flags[31:16] is phy_addr[47:32] */
121 165
122enum hpt_iop_request_type { 166enum hpt_iop_request_type {
123 IOP_REQUEST_TYPE_GET_CONFIG = 0, 167 IOP_REQUEST_TYPE_GET_CONFIG = 0,
@@ -223,6 +267,13 @@ struct hpt_scsi_pointer {
223 267
224#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp) 268#define HPT_SCP(scp) ((struct hpt_scsi_pointer *)&(scp)->SCp)
225 269
270enum hptiop_family {
271 UNKNOWN_BASED_IOP,
272 INTEL_BASED_IOP,
273 MV_BASED_IOP,
274 MVFREY_BASED_IOP
275} ;
276
226struct hptiop_hba { 277struct hptiop_hba {
227 struct hptiop_adapter_ops *ops; 278 struct hptiop_adapter_ops *ops;
228 union { 279 union {
@@ -236,6 +287,22 @@ struct hptiop_hba {
236 void *internal_req; 287 void *internal_req;
237 dma_addr_t internal_req_phy; 288 dma_addr_t internal_req_phy;
238 } mv; 289 } mv;
290 struct {
291 struct hpt_iop_request_get_config __iomem *config;
292 struct hpt_iopmu_mvfrey __iomem *mu;
293
294 int internal_mem_size;
295 struct hptiop_request internal_req;
296 int list_count;
297 struct mvfrey_inlist_entry *inlist;
298 dma_addr_t inlist_phy;
299 __le32 inlist_wptr;
300 struct mvfrey_outlist_entry *outlist;
301 dma_addr_t outlist_phy;
302 __le32 *outlist_cptr; /* copy pointer shadow */
303 dma_addr_t outlist_cptr_phy;
304 __le32 outlist_rptr;
305 } mvfrey;
239 } u; 306 } u;
240 307
241 struct Scsi_Host *host; 308 struct Scsi_Host *host;
@@ -283,6 +350,7 @@ struct hpt_ioctl_k {
283}; 350};
284 351
285struct hptiop_adapter_ops { 352struct hptiop_adapter_ops {
353 enum hptiop_family family;
286 int (*iop_wait_ready)(struct hptiop_hba *hba, u32 millisec); 354 int (*iop_wait_ready)(struct hptiop_hba *hba, u32 millisec);
287 int (*internal_memalloc)(struct hptiop_hba *hba); 355 int (*internal_memalloc)(struct hptiop_hba *hba);
288 int (*internal_memfree)(struct hptiop_hba *hba); 356 int (*internal_memfree)(struct hptiop_hba *hba);
@@ -298,6 +366,8 @@ struct hptiop_adapter_ops {
298 void (*post_msg)(struct hptiop_hba *hba, u32 msg); 366 void (*post_msg)(struct hptiop_hba *hba, u32 msg);
299 void (*post_req)(struct hptiop_hba *hba, struct hptiop_request *_req); 367 void (*post_req)(struct hptiop_hba *hba, struct hptiop_request *_req);
300 int hw_dma_bit_mask; 368 int hw_dma_bit_mask;
369 int (*reset_comm)(struct hptiop_hba *hba);
370 __le64 host_phy_flag;
301}; 371};
302 372
303#define HPT_IOCTL_RESULT_OK 0 373#define HPT_IOCTL_RESULT_OK 0