Patch from Arne Redlich <agr@powerkom-dd.de>:
[mirror/scst/.git] / mpt / mpt_scst.c
1 /*
2  *  mpt_scst.c
3  *
4  *  Copyright (C) 2005 Beijing Soul Technology Co., Ltd.
5  *  Copyright (C) 2002, 2003, 2004 LSI Logic Corporation
6  *  Copyright (C) 2004 Vladislav Bolkhovitin <vst@vlnb.net>
7  *                and Leonid Stoljar
8  *
9  *  MPT SCSI target mode driver for SCST.
10  *
11  *  Originally   By: Stephen Shirron
12  *  Port to SCST By: Hu Gang <hugang@soulinfo.com>
13  *
14  *  This program is free software; you can redistribute it and/or
15  *  modify it under the terms of the GNU General Public License
16  *  as published by the Free Software Foundation; either version 2
17  *  of the License, or (at your option) any later version.
18  *
19  *  This program is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  *  GNU General Public License for more details.
23  *
24  */
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/types.h>
28 #include <linux/version.h>
29 #include <linux/blkdev.h>
30 #include <linux/interrupt.h>
31 #include <scsi/scsi.h>
32 #include <linux/seq_file.h>
33 #include <scsi/scsi_host.h>
34
35 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
36 #include <linux/pci.h>
37 #endif
38
39 #include "scst.h"
40
41 #include <scst_debug.h>
42
43 #include "mpt_scst.h"
44
45 #define MYNAM "mpt_scst"
46
47 #ifdef TRACING
48 static int trace_mpi = 0;
49
50 #define TRACE_MPI       0x80000000
51
52 #endif
53
54 #ifdef DEBUG
55 static char *mpt_state_string[] = {
56         "0",
57         "new",
58         "need data",
59         "data in",
60         "data out",
61         "processed",
62         "NULL",
63 };
64 #endif
65
66 #ifdef DEBUG
67 #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
68         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | \
69         TRACE_MGMT_DEBUG | TRACE_MINOR | TRACE_SPECIAL)
70 #else
71 # ifdef TRACING
72 #define SCST_DEFAULT_MPT_LOG_FLAGS (TRACE_FUNCTION | TRACE_PID | \
73         TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MINOR | TRACE_SPECIAL)
74 # endif
75 #endif
76
77 static MPT_STM_PRIV *mpt_stm_priv[MPT_MAX_ADAPTERS+1];
78
79 static int set_aliases_in_fcportpage1 = 1;
80 static int num_aliases = 0;
81 static int stm_context = 0;
82
83 static int mpt_stm_adapter_online(MPT_STM_PRIV *priv);
84 static void mpt_stm_adapter_dispose(MPT_STM_PRIV *priv);
85 static int mpt_stm_adapter_install(MPT_ADAPTER *ioc);
86
87 static int __init _mpt_stm_init(void);
88
89 static void stmapp_set_status(MPT_STM_PRIV *priv, CMD *cmd, int status);
90 static void stmapp_tgt_command(MPT_STM_PRIV *priv, u32 reply_word);
91 static void stm_cmd_buf_post(MPT_STM_PRIV *priv, int index);
92
93 static void stm_tgt_reply_high_pri(MPT_ADAPTER *ioc,
94                 TargetCmdBufferPostErrorReply_t *rep);
95 static void stm_target_reply_error(MPT_ADAPTER *ioc, TargetErrorReply_t *rep);
96 static void stmapp_target_error(MPT_STM_PRIV *priv, u32 reply_word, int index,
97                 int status, int reason);
98 static void stm_link_service_reply(MPT_ADAPTER *ioc,
99                        LinkServiceBufferPostReply_t *rep);
100 static void stm_link_service_rsp_reply(MPT_ADAPTER *ioc,
101                            LinkServiceRspRequest_t *req, LinkServiceRspReply_t *rep);
102 static void stmapp_set_sense_info(MPT_STM_PRIV *priv,
103                       CMD *cmd, int sense_key, int asc, int ascq);
104 static void stmapp_srr_adjust_offset(MPT_STM_PRIV *priv, int index);
105 static void stmapp_srr_convert_ta_to_tss(MPT_STM_PRIV *priv, int index);
106 static void stmapp_abts_process(MPT_STM_PRIV *priv,
107                     int rx_id, LinkServiceBufferPostReply_t *rep, int index);
108 static int stm_do_config_action(MPT_STM_PRIV *priv,
109                      int action, int type, int number, int address, int length,
110                      int sleep);
111 static int stm_get_config_page(MPT_STM_PRIV *priv,
112                     int type, int number, int address, int sleep);
113 static int stm_set_config_page(MPT_STM_PRIV *priv,
114                     int type, int number, int address, int sleep);
115 static void stm_cmd_buf_post_list(MPT_STM_PRIV *priv, int index);
116 static int stm_send_target_status(MPT_STM_PRIV *priv,
117                        u32 reply_word, int index, int flags, int lun, int tag);
118 static void stm_send_els(MPT_STM_PRIV *priv, LinkServiceBufferPostReply_t *rep,
119              int index, int length);
120 static void stm_link_serv_buf_post(MPT_STM_PRIV *priv, int index);
121
122 static void stm_wait(MPT_STM_PRIV *priv, int milliseconds, int sleep);
123 static int stm_wait_for(MPT_STM_PRIV *priv, volatile int *flag, int seconds,
124              int sleep);
125 static void stmapp_srr_process(MPT_STM_PRIV *priv, int rx_id, int r_ctl,
126                 u32 offset, LinkServiceBufferPostReply_t *rep, int index);
127 static void stm_set_scsi_port_page1(MPT_STM_PRIV *priv, int sleep);
128
129 #ifdef DEBUG
130 #define trace_flag mpt_trace_flag
131 unsigned long mpt_trace_flag = TRACE_FUNCTION | TRACE_OUT_OF_MEM | TRACE_SPECIAL;
132 #else
133 # ifdef TRACING
134 #define trace_flag mpt_trace_flag
135 unsigned long mpt_trace_flag = TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_SPECIAL;
136 # endif
137 #endif
138
139 static int
140 mpt_target_show(struct seq_file *seq, void *v)
141 {
142         struct mpt_tgt *tgt = (struct mpt_tgt *)seq->private;
143         MPT_ADAPTER *ioc = tgt->priv->ioc;
144         MPT_STM_PRIV *priv = tgt->priv;
145
146         TRACE_ENTRY();
147         TRACE_DBG("priv %p, tgt %p", priv, tgt);
148
149         sBUG_ON(tgt == NULL);
150         sBUG_ON(ioc == NULL);
151
152         seq_printf(seq, "ProductID        :0x%04x (%s)\n"
153                         "Target Enable    :%s\n",
154                         ioc->facts.ProductID,
155                         ioc->prod_name,
156                         tgt->target_enable ? "True" : "False");
157
158 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15))
159         if (ioc->bus_type == SCSI) {
160 #else
161         if (ioc->bus_type == SPI) {
162 #endif
163                 int i = 0;
164                 seq_printf(seq, "Target ID        :%d\n"
165                                 "Capabilities     :0x%x\n"
166                                 "PhysicalInterface:0x%x\n",
167                                 priv->port_id,
168                                 priv->SCSIPortPage0.Capabilities,
169                                 priv->SCSIPortPage0.PhysicalInterface);
170
171                 seq_printf(seq, "Configuration    :0x%x\n"
172                                 "OnBusTimerValue  :0x%x\n"
173                                 "TargetConfig     :0x%x\n"
174                                 "IDConfig         :0x%x\n",
175                                 priv->SCSIPortPage1.Configuration,
176                                 priv->SCSIPortPage1.OnBusTimerValue,
177                                 priv->SCSIPortPage1.TargetConfig,
178                                 priv->SCSIPortPage1.IDConfig);
179
180                 seq_printf(seq, "PortFlags        :0x%x\n"
181                                 "PortSettings     :0x%x\n",
182                                 priv->SCSIPortPage2.PortFlags,
183                                 priv->SCSIPortPage2.PortSettings);
184 #if 0
185                 for (i = 0; i < 16; i++) {
186                         seq_printf(seq, " DeviceSeting %02d: 0x%x 0x%x 0x%x\n",
187                                         priv->SCSIPortPage2.DeviceSettings[i].Timeout,
188                                         priv->SCSIPortPage2.DeviceSettings[i].SyncFactor,
189                                         priv->SCSIPortPage2.DeviceSettings[i].DeviceFlags);
190                 }
191 #endif
192                 for (i = 0; i < NUM_SCSI_DEVICES; i++) {
193                         seq_printf(seq, "  Device %02d: 0x%x, 0x%x\n",
194                                         i,
195                                         priv->SCSIDevicePage1[i].RequestedParameters,
196                                         priv->SCSIDevicePage1[i].Configuration);
197                 }
198         }
199
200         if (ioc->bus_type == FC) {
201                 seq_printf(seq, "WWN              :%08X%08X:%08X%08X\n",
202                                 ioc->fc_port_page0[0].WWNN.High,
203                                 ioc->fc_port_page0[0].WWNN.Low,
204                                 ioc->fc_port_page0[0].WWPN.High,
205                                 ioc->fc_port_page0[0].WWPN.Low);
206         }
207
208         TRACE_EXIT();
209         return 0;
210 }
211
212 static int
213 mpt_proc_target_write(struct file *file, const char __user *buf,
214                         size_t length, loff_t *off)
215 {
216
217         struct mpt_tgt *tgt = (struct mpt_tgt *)PDE(file->f_dentry->d_inode)->data;
218         MPT_ADAPTER *ioc = tgt->priv->ioc;
219         int res = 0;
220         char tmp[32+1];
221
222         TRACE_ENTRY();
223         res = min(32, (int)length);
224         if (copy_from_user(tmp, buf, res)) {
225                 res = -EFAULT;
226                 goto out;
227         }
228         tmp[res] = 0;
229
230         TRACE_DBG("buff '%s'", tmp);
231         if (strncmp("target:enable", tmp, strlen("target:enable")) == 0) {
232                 TRACE_DBG("Enable Target, %d, %d", ioc->id, tgt->target_enable);
233                 if (tgt->target_enable != 1) {
234                         mpt_stm_adapter_online(mpt_stm_priv[ioc->id]);
235                         tgt->target_enable = 1;
236                 }
237         }
238
239         if (strncmp("target:disable", tmp, strlen("target:disable")) == 0) {
240                 TRACE_DBG("Disable Target %d, %d", ioc->id, tgt->target_enable);
241                 if (tgt->target_enable != 0) {
242                         /* FIXME */
243                         tgt->target_enable = 0;
244                 }
245         }
246
247         if (strncmp("target_id:", tmp, strlen("target_id:")) == 0) {
248                 char *s = tmp + strlen("target_id:");
249                 int id = simple_strtoul(s, NULL, 0);
250                 if (id < MPT_MAX_SCSI_DEVICES) {
251                         if (IsScsi(tgt->priv)) {
252                                 TRACE_DBG("Changing target id to %d\n",
253                                                 id);
254                                 tgt->priv->port_id = id;
255                                 stm_set_scsi_port_page1(tgt->priv,
256                                                 NO_SLEEP);
257                         }
258                 }
259         }
260
261 out:
262         TRACE_EXIT_RES(res);
263
264         return length;
265 }
266
267 static struct scst_proc_data mpt_target_proc_data = {
268         SCST_DEF_RW_SEQ_OP(mpt_proc_target_write)
269         .show = mpt_target_show,
270 };
271
272 static int mpt_target_detect(struct scst_tgt_template *temp1);
273 static int mpt_target_release(struct scst_tgt *scst_tgt);
274 static int stmapp_pending_sense(struct mpt_cmd *mpt_cmd);
275 static int mpt_xmit_response(struct scst_cmd *scst_cmd);
276 static void mpt_inquiry_no_tagged_commands(MPT_STM_PRIV *priv,
277                 struct scst_cmd *scst_cmd);
278 static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd);
279 static void mpt_on_free_cmd(struct scst_cmd *scst_cmd);
280 static void mpt_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd);
281 static int mpt_handle_task_mgmt(MPT_STM_PRIV * priv, u32 reply_word,
282                 int task_mgmt, int lun);
283 static int mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context);
284
285 static struct scst_tgt_template tgt_template = {
286         .name = MYNAM,
287         .sg_tablesize = 128, /* FIXME */
288         .use_clustering = 1,
289 #ifdef DEBUG_WORK_IN_THREAD
290         .xmit_response_atomic = 0,
291         .rdy_to_xfer_atomic = 0,
292 #else
293         .xmit_response_atomic = 1,
294         .rdy_to_xfer_atomic = 1,
295 #endif
296         .detect = mpt_target_detect,
297         .release = mpt_target_release,
298         .xmit_response = mpt_xmit_response,
299         .rdy_to_xfer = mpt_rdy_to_xfer,
300         .on_free_cmd = mpt_on_free_cmd,
301         .task_mgmt_fn_done = mpt_task_mgmt_fn_done,
302 };
303
304 static inline void
305 mpt_msg_frame_free(MPT_STM_PRIV *priv, int index)
306 {
307         MPT_ADAPTER *ioc = priv->ioc;
308         if (priv->current_mf[index] != NULL) {
309                 TRACE_DBG("%s: free mf index %d, %p", ioc->name,
310                                 MF_TO_INDEX(priv->current_mf[index]),
311                                 priv->current_mf[index]);
312                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
313                 priv->current_mf[index] = NULL;
314         }
315 }
316
317 static inline MPT_FRAME_HDR *
318 mpt_msg_frame_alloc(MPT_ADAPTER *ioc, int index)
319 {
320         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
321         MPT_FRAME_HDR *mf;
322
323         if (index != -1) {
324                 TRACE_DBG("%s: current_mf %p, index %d",
325                                 ioc->name, priv->current_mf[index], index);
326                 WARN_ON(priv->current_mf[index] != NULL);
327         }
328
329         mf = mpt_get_msg_frame(stm_context, _IOC_ID);
330
331         if (mf == NULL) {
332                 sBUG_ON(1);
333         }
334
335         if (index != -1) {
336                 priv->current_mf[index] = mf;
337         }
338
339         TRACE_DBG("%s: alloc mf index %d, %p, %d", ioc->name,
340                         MF_TO_INDEX(mf), mf, index);
341
342         return mf;
343 }
344
345 static int _mpt_ada_nums = 0;
346
347 static int
348 mptstm_probe(struct pci_dev *pdev, const struct pci_device_id *id)
349 {
350     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
351     int ret = 0;
352     struct mpt_tgt *tgt;
353     struct proc_dir_entry *p;
354     struct proc_dir_entry *root;
355     char name[4];
356
357     TRACE_ENTRY();
358     ret = mpt_stm_adapter_install(ioc);
359     if (ret != 0) {
360             goto out;
361     }
362
363     tgt = kmalloc(sizeof(*tgt), GFP_KERNEL);
364     TRACE_MEM("kmalloc(GFP_KERNEL) for tgt (%d), %p",
365               sizeof(*tgt), tgt);
366     if (tgt == NULL) {
367             TRACE(TRACE_OUT_OF_MEM, "%s",
368                   "Allocation of tgt failed");
369             ret = -ENOMEM;
370             goto out;
371     }
372     memset(tgt, 0, sizeof(*tgt));
373     tgt->priv = mpt_stm_priv[ioc->id];
374     tgt->target_enable = 0;
375     tgt->priv->port_id = 1;
376     /* tgt->priv->scsi_port_config = MPI_SCSIPORTPAGE1_TARGCONFIG_INIT_TARG; */
377     tgt->priv->scsi_port_config = MPI_SCSIPORTPAGE1_TARGCONFIG_TARG_ONLY;
378     /* tgt->priv->scsi_id_config = 0x7; */
379     tgt->priv->scsi_id_config = 0;
380     atomic_set(&tgt->sess_count, 0);
381     init_waitqueue_head(&tgt->waitQ);
382
383     tgt->scst_tgt = scst_register(&tgt_template, MYNAM);
384     if (tgt->scst_tgt == NULL) {
385             PRINT_ERROR(MYNAM ": scst_register() "
386                         "failed for host %p", pdev);
387
388             ret = -ENODEV;
389             goto out;
390     }
391
392     root = scst_proc_get_tgt_root(&tgt_template);
393     scnprintf(name, sizeof(name), "%d", ioc->id);
394     mpt_target_proc_data.data = (void *)tgt;
395     p = scst_create_proc_entry(root, name,
396                                 &mpt_target_proc_data);
397     if (p == NULL) {
398             PRINT_ERROR("Not enough memory to register "
399                             "target driver %s entry %s in /proc",
400                             tgt_template.name, name);
401             scst_unregister(tgt->scst_tgt);
402             ret = -ENOMEM;
403             goto out;
404     }
405
406     scst_tgt_set_tgt_priv(tgt->scst_tgt, tgt);
407     mpt_stm_priv[ioc->id]->tgt = tgt;
408     _mpt_ada_nums ++;
409
410  out:
411
412     TRACE_EXIT_RES(ret);
413
414     return ret;
415 }
416
417 static void
418 mptstm_remove(struct pci_dev *pdev)
419 {
420     MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
421     MPT_STM_PRIV *priv;
422
423         priv = mpt_stm_priv[ioc->id];
424         if (priv != NULL) {
425                 mpt_stm_adapter_dispose(priv);
426         }
427 }
428
429 static struct mpt_pci_driver mptstm_driver = {
430     .probe = mptstm_probe,
431     .remove = mptstm_remove,
432 };
433
434 /*
435  * mpt_target_detect
436  *
437  * this function is intended to detect the target adapters that are present in
438  * the system. Each found adapter should be registered by calling
439  * scst_register(). The function should return a value >= 0 to signify
440  * the number of detected target adapters. A negative value should be
441  * returned whenever there is an error.
442  */
443 static int mpt_target_detect(struct scst_tgt_template *templ)
444 {
445         int ret  = 0;
446
447         TRACE_ENTRY();
448         ret = _mpt_stm_init();
449         if (ret != 0) {
450                 goto out;
451         }
452
453         if (mpt_device_driver_register(&mptstm_driver, MPTSTM_DRIVER)) {
454                 printk(KERN_WARNING MYNAM
455                        ": failed to register for device driver callbacks\n");
456                 ret = -ENODEV;
457                 goto out;
458         }
459
460         ret = _mpt_ada_nums;
461
462  out:
463         TRACE_EXIT_RES(ret);
464
465         return ret;
466 }
467
468 static struct scst_cmd *
469 _stm_target_command(MPT_STM_PRIV *priv, int reply_word,
470                     struct mpt_cmd *mpt_cmd)
471 {
472         u8 *cdb;
473         int lun, tag, dl, alias, index, init_index, task_mgmt;
474         char alias_lun[32];
475         CMD *cmd;
476         struct scst_cmd *scst_cmd;
477         struct mpt_sess *sess = mpt_cmd->sess;
478 #ifdef DEBUG
479         MPT_ADAPTER *ioc = priv->ioc;
480 #endif
481         /*
482          * Get the CBD, LUN, tag,  Task Mgmt flags, and data length from the
483          * receive packet
484          */
485         TRACE_ENTRY();
486
487         index = GET_IO_INDEX(reply_word);
488         init_index = GET_INITIATOR_INDEX(reply_word);
489
490         cmd = &priv->hw->cmd_buf[index];
491
492         if (IsScsi(priv)) {
493                 SCSI_CMD *scsi_cmd = (SCSI_CMD *)cmd->cmd;
494
495                 cdb = scsi_cmd->CDB;
496                 lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
497                 tag = scsi_cmd->Tag;
498                 task_mgmt = scsi_cmd->TaskManagementFlags;
499                 dl = 0;
500                 /*TRACE_DBG("AliasID %d, %d", scsi_cmd->AliasID, priv->port_id);*/
501                 if (reply_word & TARGET_MODE_REPLY_ALIAS_MASK) {
502                         alias = (scsi_cmd->AliasID - priv->port_id) & 15;
503                         sprintf(alias_lun, "alias %d lun %d", alias, lun);
504                 } else {
505                         alias = 0;
506                         sprintf(alias_lun, "lun %d", lun);
507                 }
508         } else if (IsSas(priv)) {
509                 SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
510
511                 cdb = ssp_cmd->CDB;
512                 lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
513                 if (ssp_cmd->FrameType == SSP_TASK_FRAME) {
514                         SSP_TASK        *ssp_task = (SSP_TASK *)cmd->cmd;
515
516                         tag = ssp_task->ManagedTaskTag;
517                         task_mgmt = ssp_task->TaskManagementFunction;
518                 } else {
519                         tag = ssp_cmd->InitiatorTag;
520                         task_mgmt = 0;
521                 }
522                 dl = 0;
523                 alias = 0;
524                 sprintf(alias_lun, "lun %d", lun);
525         } else {
526                 FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
527
528                 cdb = fcp_cmd->FcpCdb;
529                 lun = get2bytes(fcp_cmd->FcpLun, 0);
530                 tag = 0;
531                 task_mgmt = fcp_cmd->FcpCntl[2];
532                 dl = be32_to_cpu(fcp_cmd->FcpDl);
533                 if (reply_word & TARGET_MODE_REPLY_ALIAS_MASK) {
534                         alias = fcp_cmd->AliasIndex;
535                         sprintf(alias_lun, "alias %d lun %d", alias, lun);
536                 } else {
537                         alias = 0;
538                         sprintf(alias_lun, "lun %d", lun);
539                 }
540         }
541
542         cmd->reply_word = reply_word;
543         cmd->alias = alias;
544         cmd->lun = lun;
545         cmd->tag = tag;
546
547         TRACE_DBG("%s: cmd %p, re_word %x, alias %x, lun %x, tag %x,"
548                         "%s, init_idx %d, %p, %d",
549                         ioc->name, cmd, reply_word, alias, lun, tag, alias_lun,
550                         init_index, priv->scst_cmd[index], dl);
551
552         mpt_cmd->CMD = cmd;
553         {
554                 uint16_t _lun = lun;
555                 _lun = swab16(le16_to_cpu(_lun));
556                 scst_cmd = scst_rx_cmd(sess->scst_sess, (uint8_t *)&_lun,
557                                 sizeof(_lun), cdb, MPT_MAX_CDB_LEN, SCST_ATOMIC);
558         }
559         if (scst_cmd == NULL) {
560                 PRINT_ERROR(MYNAM ": scst_rx_cmd() failed for %p", cmd);
561                 goto out;
562         }
563         TRACE_DBG("scst cmd %p, index %d", priv->scst_cmd[index], index);
564
565         WARN_ON(priv->scst_cmd[index] != 0);
566         priv->scst_cmd[index] = scst_cmd;
567
568         scst_cmd_set_tag(scst_cmd, tag);
569         scst_cmd_set_tgt_priv(scst_cmd, mpt_cmd);
570
571         /* FIXME scst_cmd_set_expected */
572 out:
573         TRACE_EXIT();
574
575         return scst_cmd;
576 }
577
578 static void
579 mpt_send_busy(struct mpt_cmd *cmd)
580 {
581         stmapp_set_status(cmd->priv, cmd->CMD, STS_BUSY);
582 }
583
584 static void
585 mpt_alloc_session_done(struct scst_session *scst_sess, void *data, int result)
586 {
587         struct mpt_sess *sess = (struct mpt_sess *) data;
588         struct mpt_tgt *tgt = sess->tgt;
589         struct mpt_cmd *cmd = NULL;
590         int rc = 0;
591
592         TRACE_ENTRY();
593         if (result == 0) {
594                 scst_sess_set_tgt_priv(scst_sess, sess);
595
596                 while (!list_empty(&sess->delayed_cmds)) {
597                         cmd = list_entry(sess->delayed_cmds.next,
598                                          typeof(*cmd), delayed_cmds_entry);
599                         list_del(&cmd->delayed_cmds_entry);
600                         if (rc == 0)
601                                 rc = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_THREAD);
602                         if (rc != 0) {
603                                 PRINT_INFO(MYNAM ": Unable to get the command, sending BUSY state %p",
604                                            cmd);
605                                 mpt_send_busy(cmd);
606                                 kfree(cmd);
607                         }
608                 }
609         } else {
610                 PRINT_INFO(MYNAM ": Session initialization failed, "
611                            "sending BUSY status to all deferred commands %p",
612                            cmd);
613                 while (!list_empty(&sess->delayed_cmds)) {
614                         cmd = list_entry(sess->delayed_cmds.next,
615                                          typeof(*cmd), delayed_cmds_entry);
616                         list_del(&cmd->delayed_cmds_entry);
617                         TRACE(TRACE_MGMT, "Command <%p> Busy", cmd);
618                         mpt_send_busy(cmd);
619                         kfree(cmd);
620                 }
621                 tgt->sess[sess->init_index] = NULL;
622
623                 TRACE_MEM("kfree for sess %p", sess);
624                 kfree(sess);
625
626                 if (atomic_dec_and_test(&tgt->sess_count))
627                                 wake_up_all(&tgt->waitQ);
628         }
629
630         __clear_bit(MPT_SESS_INITING, &sess->sess_flags);
631
632         TRACE_EXIT();
633         return;
634 }
635
636 static int
637 mpt_send_cmd_to_scst(struct mpt_cmd *cmd, int context)
638 {
639         int res = 0;
640
641         TRACE_ENTRY();
642
643         cmd->scst_cmd = _stm_target_command(cmd->priv, cmd->reply_word, cmd);
644         if (cmd->scst_cmd == NULL) {
645                 res = -EFAULT;
646                 goto out;
647         }
648 #ifdef DEBUG_WORK_IN_THREAD
649         context = SCST_CONTEXT_THREAD;
650 #endif
651         scst_cmd_init_done(cmd->scst_cmd, context);
652
653  out:
654         TRACE_EXIT_RES(res);
655
656         return res;
657 }
658
659 static void
660 stm_send_target_status_deferred(MPT_STM_PRIV *priv,
661                 u32 reply_word, int index)
662 {
663         int ret = 0;
664         MPT_ADAPTER         *ioc = priv->ioc;
665         MPT_FRAME_HDR       *mf;
666         TargetStatusSendRequest_t   *req;
667
668         TRACE_ENTRY();
669         mf = priv->status_deferred_mf[index];
670         TRACE_DBG("mf %p, index %d", mf, index);
671         req = (TargetStatusSendRequest_t *)mf;
672
673         priv->io_state[index] |= IO_STATE_STATUS_SENT;
674
675         priv->current_mf[index] = mf;
676         priv->status_deferred_mf[index] = NULL;
677         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
678                 ret = mpt_send_handshake_request(stm_context, _IOC_ID,
679                                 sizeof(*req), (u32 *)req _HS_SLEEP);
680         } else {
681                 mpt_put_msg_frame(stm_context, _IOC_ID, mf);
682         }
683
684         TRACE_EXIT_RES(ret);
685 }
686
687 static void
688 stm_data_done(MPT_ADAPTER *ioc, u32 reply_word,
689                 struct scst_cmd *scst_cmd, struct mpt_cmd *cmd, int index)
690 {
691         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
692
693         TRACE_ENTRY();
694         TRACE_DBG("scst cmd %p, index %d, data done",  scst_cmd, index);
695
696         if (scst_cmd_get_resp_data_len(scst_cmd) > 0) {
697                 TRACE_DBG("clear the data flags <%p>", scst_cmd);
698                 sBUG_ON(scst_cmd_get_sg_cnt(scst_cmd) == 0);
699                 pci_unmap_sg(priv->ioc->pcidev,
700                         scst_cmd_get_sg(scst_cmd),
701                         scst_cmd_get_sg_cnt(scst_cmd),
702                         scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
703         }
704         TRACE_EXIT();
705 }
706
707 void
708 stm_tgt_reply(MPT_ADAPTER *ioc, u32 reply_word)
709 {
710         MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
711         int index;
712         int init_index;
713         struct scst_cmd *scst_cmd;
714         struct mpt_cmd *cmd;
715         volatile int *io_state;
716
717         TRACE_ENTRY();
718
719         index = GET_IO_INDEX(reply_word);
720         init_index = GET_INITIATOR_INDEX(reply_word);
721         scst_cmd = priv->scst_cmd[index];
722         io_state = priv->io_state + index;
723
724         TRACE_DBG("index %d, state %x, scst cmd %p, current_mf %p",
725                         index, *io_state, scst_cmd, priv->current_mf[index]);
726         /*
727          * if scst_cmd is NULL it show the command buffer not using by
728          * SCST, let parse the CDB
729          */
730         if (scst_cmd == NULL) {
731                 WARN_ON((*io_state & ~IO_STATE_HIGH_PRIORITY) != IO_STATE_POSTED);
732                 *io_state &= ~IO_STATE_POSTED;
733
734                 mpt_msg_frame_free(priv, index);
735
736                 stmapp_tgt_command(priv, reply_word);
737                 goto out;
738         }
739
740         cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
741         TRACE_DBG("scst cmd %p, index %d, cmd %p, cmd state %s",
742                   scst_cmd, index, cmd, mpt_state_string[cmd->state]);
743
744         if (cmd->state == MPT_STATE_NEED_DATA) {
745                 int context = SCST_CONTEXT_TASKLET;
746                 int rx_status = SCST_RX_STATUS_SUCCESS;
747
748                 cmd->state = MPT_STATE_DATA_IN;
749
750 #ifdef DEBUG_WORK_IN_THREAD
751                 context = SCST_CONTEXT_THREAD;
752 #endif
753                 TRACE_DBG("Data received, context %x, rx_status %d",
754                                 context, rx_status);
755
756                 sBUG_ON(!(*io_state & IO_STATE_DATA_SENT));
757                 mpt_msg_frame_free(priv, index);
758                 if (*io_state & IO_STATE_DATA_SENT) {
759                         *io_state &= ~IO_STATE_DATA_SENT;
760                         stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
761                 }
762 #if 0
763                 if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
764                         TRACE_DBG("%s", "io state auto repost");
765                         *io_state = IO_STATE_POSTED;
766                 } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
767                         TRACE_DBG("%s", "io state");
768                         stm_cmd_buf_post(priv, index);
769                 }
770 #endif
771                 scst_rx_data(scst_cmd, rx_status, context);
772
773                 goto out;
774         }
775
776         if (*io_state & IO_STATE_STATUS_SENT) {
777                 /*
778                  *  status (and maybe data too) was being sent, so repost the
779                  *  command buffer
780                  */
781                 *io_state &= ~IO_STATE_STATUS_SENT;
782                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
783                 if (*io_state & IO_STATE_DATA_SENT) {
784                         *io_state &= ~IO_STATE_DATA_SENT;
785                         stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
786                 }
787                 TRACE_DBG("set priv->scst_cmd[%d] = NULL", index);
788                 priv->scst_cmd[index] = NULL;
789                 if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
790                         TRACE_DBG("%s", "io state auto repost");
791                         *io_state = IO_STATE_POSTED;
792                 } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
793                         TRACE_DBG("%s", "io state");
794                         stm_cmd_buf_post(priv, index);
795                 }
796
797                 /*
798                  * figure out how we're handling cached sense data.
799                  */
800                 if (IsScsi(priv)) {
801                         switch (atomic_read(&priv->pending_sense[init_index])) {
802                                 /* attempt to send status and sense succeeded */
803                                 case MPT_STATUS_SENSE_ATTEMPT:
804                                         atomic_set(&priv->pending_sense[init_index],
805                                                 MPT_STATUS_SENSE_IDLE);
806                                         /* ToDo: check and set scst_set_delivery_status(), if necessary */
807                                         scst_tgt_cmd_done(scst_cmd);
808                                         break;
809
810                                 /* we tried to send status and sense
811                                  * simltaneously and failed.  Prepare to handle
812                                  * the next command without SCST if it is
813                                  * REQUEST_SENSE */
814                                 case MPT_STATUS_SENSE_NOT_SENT:
815                                         atomic_set(&priv->pending_sense[init_index],
816                                                 MPT_STATUS_SENSE_HANDLE_RQ);
817                                         /* ToDo: check and set scst_set_delivery_status(), if necessary */
818                                         scst_tgt_cmd_done(scst_cmd);
819                                         break;
820
821                                 /* we've handled REQUEST_SENSE ourselves and
822                                  * we're done with the command.  Clean up */
823                                 case MPT_STATUS_SENSE_HANDLE_RQ:
824                                         TRACE_DBG("%s: clearing pending sense",
825                                                         ioc->name);
826                                         atomic_set(&priv->pending_sense[init_index],
827                                                         MPT_STATUS_SENSE_IDLE);
828                                         mpt_on_free_cmd(scst_cmd);
829                                         /* scst_cmd alloced in stmapp_pending_sense */
830                                         kfree(scst_cmd);
831                                         break;
832
833                                 default:
834                                         /* nothing much to do here, we aren't
835                                          * handling cached sense/status */
836                                         /* ToDo: check and set scst_set_delivery_status(), if necessary */
837                                         scst_tgt_cmd_done(scst_cmd);
838                                         break;
839                         }
840                 } else {
841                         /* ToDo: check and set scst_set_delivery_status(), if necessary */
842                         scst_tgt_cmd_done(scst_cmd);
843                 }
844
845                 goto out;
846         }
847
848         /*
849          *  data (but not status) was being sent, so if status needs to be
850          *  set now, go ahead and do it; otherwise do nothing
851          */
852         if (*io_state & IO_STATE_DATA_SENT) {
853                 *io_state &= ~IO_STATE_DATA_SENT;
854                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
855                 stm_data_done(ioc, reply_word, scst_cmd, cmd, index);
856                 if (*io_state & IO_STATE_STATUS_DEFERRED) {
857                         *io_state &= ~IO_STATE_STATUS_DEFERRED;
858                         stm_send_target_status_deferred(priv, reply_word, index);
859                 }
860                 cmd->state = MPT_STATE_PROCESSED;
861                 goto out;
862         }
863
864         /*
865          * just insert into list
866          * bug how can i handle it
867          */
868         if (*io_state == 0 && cmd->state == MPT_STATE_NEW) {
869                 WARN_ON(1);
870                 goto out;
871         }
872 #if 0
873         if (*io_state == IO_STATE_POSTED) {
874                 TRACE_DBG("%s", "io state posted");
875                 /*
876                  *  command buffer was posted, so we now have a SCSI command
877                  */
878                 *io_state &= ~IO_STATE_POSTED;
879                 goto out;
880         }
881 #endif
882         WARN_ON(1);
883  out:
884
885         TRACE_EXIT();
886 }
887
888 static int
889 mpt_is_task_mgm(MPT_STM_PRIV *priv, u32 reply_word, int *lun)
890 {
891         int task_mgmt = 0, index;
892         CMD *cmd;
893         //struct mpt_tgt *tgt = priv->tgt;
894
895         TRACE_ENTRY();
896
897         index = GET_IO_INDEX(reply_word);
898         cmd = &priv->hw->cmd_buf[index];
899
900         if (IsScsi(priv)) {
901                 SCSI_CMD *scsi_cmd = (SCSI_CMD *)cmd->cmd;
902                 task_mgmt = scsi_cmd->TaskManagementFlags;
903                 *lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
904         } else if (IsSas(priv)) {
905                 SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
906                 if (ssp_cmd->FrameType == SSP_TASK_FRAME) {
907                         SSP_TASK *ssp_task = (SSP_TASK *)cmd->cmd;
908                         task_mgmt = ssp_task->TaskManagementFunction;
909                 }
910                 *lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
911         } else {
912                 FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
913                 task_mgmt = fcp_cmd->FcpCntl[2];
914                 *lun = get2bytes(fcp_cmd->FcpLun, 0);
915         }
916         TRACE_EXIT_RES(task_mgmt);
917
918         return task_mgmt;
919 }
920
921 static void
922 stmapp_tgt_command(MPT_STM_PRIV *priv, u32 reply_word)
923 {
924         struct mpt_tgt *tgt = NULL;
925         struct mpt_sess *sess = NULL;
926         struct mpt_cmd *cmd = NULL;
927         int init_index, res = 0, task_mgmt, lun;
928
929         TRACE_ENTRY();
930
931         tgt = priv->tgt;
932
933         task_mgmt = mpt_is_task_mgm(priv, reply_word, &lun);
934         if (task_mgmt) {
935                 mpt_handle_task_mgmt(priv, reply_word, task_mgmt, lun);
936         }
937
938         init_index = GET_INITIATOR_INDEX(reply_word);
939
940         if (test_bit(MPT_TGT_SHUTDOWN, &tgt->tgt_flags)) {
941                 TRACE_DBG("New command while the device %p is shutting down", tgt);
942                 res = -EFAULT;
943                 goto out;
944         }
945
946         cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
947         TRACE_MEM("kmalloc(GFP_ATOMIC) for cmd (%d): %p", sizeof(*cmd), cmd);
948         if (cmd == NULL) {
949                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of cmd failed");
950                 res = -ENOMEM;
951                 goto out;
952         }
953
954         memset(cmd, 0, sizeof(*cmd));
955         cmd->priv = priv;
956         cmd->reply_word = reply_word;
957         cmd->state = MPT_STATE_NEW;
958
959         sess = tgt->sess[init_index];
960         if (sess == NULL) {
961                 sess = kmalloc(sizeof(*sess), GFP_ATOMIC);
962                 if (sess == NULL) {
963                         TRACE(TRACE_OUT_OF_MEM, "%s",
964                               "Allocation of sess failed");
965                         res = -ENOMEM;
966                         goto out_free_cmd;
967                 }
968                 /* WWPN */
969
970                 atomic_inc(&tgt->sess_count);
971                 smp_mb__after_atomic_inc();
972
973                 memset(sess, 0, sizeof(*sess));
974                 sess->tgt = tgt;
975                 sess->init_index = init_index;
976                 INIT_LIST_HEAD(&sess->delayed_cmds);
977
978                 sess->scst_sess = scst_register_session(tgt->scst_tgt, 1,
979                                                         "", sess, mpt_alloc_session_done);
980                 if (sess->scst_sess == NULL) {
981                         PRINT_ERROR(MYNAM ": scst_register_session failed %p",
982                                     tgt);
983                         res = -EFAULT;
984                         goto out_free_sess;
985                 }
986
987                 __set_bit(MPT_SESS_INITING, &sess->sess_flags);
988
989                 tgt->sess[init_index] = sess;
990                 scst_sess_set_tgt_priv(sess->scst_sess, sess);
991
992                 cmd->sess = sess;
993                 list_add_tail(&cmd->delayed_cmds_entry, &sess->delayed_cmds);
994                 goto out;
995         }
996
997         /* seesion is ready let us do it */
998         cmd->sess = sess;
999         if (test_bit(MPT_SESS_INITING, &sess->sess_flags)) {
1000                 list_add_tail(&cmd->delayed_cmds_entry, &sess->delayed_cmds);
1001         } else {
1002                 /* if there is pending sense left over from the last command,
1003                  * we need to send that if this is a REQUEST SENSE command.
1004                  * Otherwise send the command to SCST */
1005                 if (!stmapp_pending_sense(cmd)) {
1006                         res = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_TASKLET);
1007                         /*res = mpt_send_cmd_to_scst(cmd, SCST_CONTEXT_DIRECT_ATOMIC);*/
1008                         if (res != 0)
1009                                 goto out_free_cmd;
1010                 }
1011         }
1012
1013  out:
1014         TRACE_EXIT();
1015         return;
1016
1017  out_free_sess:
1018         TRACE_MEM("kfree for sess %p", sess);
1019         kfree(sess);
1020
1021         if (atomic_dec_and_test(&tgt->sess_count))
1022                 wake_up_all(&tgt->waitQ);
1023         /* go through */
1024  out_free_cmd:
1025         TRACE_MEM("kfree for cmd %p", cmd);
1026         kfree(cmd);
1027         goto out;
1028 }
1029
1030 /*
1031  * mpt_target_release
1032  *
1033  * this function is
1034  * intended to free up the resources allocated to the device. The function
1035  * should return 0 to indicate successful release or a negative value if
1036  * there are some issues with the release. In the current version of SCST
1037  * the return value is ignored. Must be defined.
1038  */
1039 static int mpt_target_release(struct scst_tgt *scst_tgt)
1040 {
1041         /* FIXME */
1042         return 0;
1043 }
1044
1045 struct mpt_prm
1046 {
1047         struct mpt_tgt *tgt;
1048         uint16_t seg_cnt;
1049         unsigned short use_sg;
1050         struct scatterlist *sg;
1051         unsigned int bufflen;
1052         void *buffer;
1053         scst_data_direction data_direction;
1054         uint16_t rq_result;
1055         uint16_t scsi_status;
1056         unsigned char *sense_buffer;
1057         unsigned int sense_buffer_len;
1058         struct mpt_cmd *cmd;
1059 };
1060
1061 static inline void
1062 mpt_dump_sge(MPT_SGE *sge, struct scatterlist *sg)
1063 {
1064         if (sge) {
1065                 void *address = NULL;
1066                 struct page *page = NULL;
1067                 address = bus_to_virt(sge->address);
1068                 page = virt_to_page(address);
1069                 TRACE_DBG("address %p, length %x, count %d, page %p",
1070                                 address, sge->length, page_count(page), page);
1071                 TRACE_BUFFER("sge data", address, min(sge->length, (u32)0x10));
1072         }
1073         if (sg) {
1074                 TRACE_DBG("sg %p, page %p, %p, offset %d, dma address %x, len %d",
1075                                 sg, sg_page(sg), page_address(sg_page(sg)),
1076                                 sg->offset, sg->dma_address, sg->length);
1077                 TRACE_BUFFER("sg data", page_address(sg_page(sg)), (u32)0x10);
1078         }
1079 }
1080
1081 /* FIXME
1082  *
1083  * use_sg can not bigger then NUM_SGES
1084  *
1085  */
1086 static inline void
1087 mpt_sge_to_sgl(struct mpt_prm *prm, MPT_STM_PRIV *priv, MPT_SGL *sgl)
1088 {
1089         unsigned int bufflen = prm->bufflen;
1090         int i;
1091
1092         TRACE_ENTRY();
1093         TRACE_DBG("bufflen %d, %p", bufflen, prm->buffer);
1094         sBUG_ON(prm->use_sg == 0);
1095
1096         prm->sg = (struct scatterlist *)prm->buffer;
1097         prm->seg_cnt = pci_map_sg(priv->ioc->pcidev, prm->sg, prm->use_sg,
1098                                    scst_to_tgt_dma_dir(prm->data_direction));
1099
1100         pci_dma_sync_sg_for_cpu(priv->ioc->pcidev, prm->sg, prm->use_sg,
1101                         scst_to_tgt_dma_dir(prm->data_direction));
1102         for (i = 0; i < prm->use_sg; i++) {
1103                 sgl->sge[i].length = sg_dma_len(&prm->sg[i]);
1104                 sgl->sge[i].address = sg_dma_address(&prm->sg[i]);
1105
1106                 TRACE_DBG("%d, %d", bufflen, prm->sg[i].length);
1107                 if (bufflen < prm->sg[i].length) {
1108                         sgl->sge[i].length = bufflen;
1109                 }
1110                 mpt_dump_sge(&sgl->sge[i], &prm->sg[i]);
1111                 bufflen -= sgl->sge[i].length;
1112         }
1113         pci_dma_sync_sg_for_device(priv->ioc->pcidev, prm->sg, prm->use_sg,
1114                         scst_to_tgt_dma_dir(prm->data_direction));
1115
1116         sgl->num_sges = prm->seg_cnt;
1117
1118         TRACE_EXIT();
1119 }
1120
1121 static inline void
1122 mpt_set_sense_info(MPT_STM_PRIV *priv, CMD *cmd, int len, u8 *sense_buf)
1123 {
1124         u8 *info = NULL;
1125
1126         TRACE_ENTRY();
1127
1128         if (IsScsi(priv)) {
1129                 SCSI_RSP    *rsp = (SCSI_RSP *)cmd->rsp;
1130
1131                 rsp->Status = STS_CHECK_CONDITION;
1132                 rsp->Valid |= SCSI_SENSE_LEN_VALID;
1133                 rsp->SenseDataListLength = cpu_to_be32(len);
1134                 info = rsp->SenseData;
1135                 if (rsp->Valid & SCSI_RSP_LEN_VALID) {
1136                         info += be32_to_cpu(rsp->PktFailuresListLength);
1137                 }
1138         } else if (IsSas(priv)) {
1139                 SSP_RSP     *rsp = (SSP_RSP *)cmd->rsp;
1140
1141                 rsp->Status = STS_CHECK_CONDITION;
1142                 rsp->DataPres |= SSP_SENSE_LEN_VALID;
1143                 rsp->SenseDataLength = cpu_to_be32(len);
1144                 info = rsp->ResponseSenseData;
1145                 if (rsp->DataPres & SSP_RSP_LEN_VALID) {
1146                         info += be32_to_cpu(rsp->ResponseDataLength);
1147                 }
1148         } else {
1149                 FCP_RSP     *rsp = (FCP_RSP *)cmd->rsp;
1150
1151                 rsp->FcpStatus = STS_CHECK_CONDITION;
1152                 rsp->FcpFlags |= FCP_SENSE_LEN_VALID;
1153                 rsp->FcpSenseLength = cpu_to_be32(len);
1154                 info = rsp->FcpSenseData - sizeof(rsp->FcpResponseData);
1155                 if (rsp->FcpFlags & FCP_RSP_LEN_VALID) {
1156                         info += be32_to_cpu(rsp->FcpResponseLength);
1157                 }
1158         }
1159
1160         sBUG_ON(info == NULL);
1161         memcpy(info, sense_buf, len);
1162 /*out:*/
1163
1164         TRACE_EXIT();
1165 }
1166
1167 static int
1168 mpt_send_tgt_data(MPT_STM_PRIV *priv, u32 reply_word,
1169                 int index, int flags, int lun, int tag, MPT_SGL *sgl,
1170                 int length, int offset)
1171 {
1172         MPT_ADAPTER *ioc = priv->ioc;
1173         TargetAssistRequest_t *req;
1174         MPT_STM_SIMPLE  *sge_simple;
1175         MPT_STM_CHAIN   *sge_chain = NULL;
1176         u32 sge_flags;
1177         int chain_length, i, j, k, init_index, res = 1;
1178         dma_addr_t dma_addr;
1179
1180         TRACE_ENTRY();
1181         req = (TargetAssistRequest_t *)mpt_msg_frame_alloc(ioc,index);
1182         memset(req, 0, sizeof(*req));
1183
1184         if (priv->exiting) {
1185                 flags &= ~TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
1186         }
1187
1188         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
1189                 flags |= TARGET_ASSIST_FLAGS_HIGH_PRIORITY;
1190                 if (flags & TARGET_ASSIST_FLAGS_AUTO_STATUS) {
1191                         flags |= TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
1192                         priv->io_state[index] |= IO_STATE_AUTO_REPOST;
1193                 }
1194         }
1195
1196         if (priv->fcp2_capable/* && priv->initiators != NULL*/) {
1197                 init_index = GET_INITIATOR_INDEX(reply_word);
1198                 /*init = priv->initiators[init_index];
1199                 if (init != NULL && init->confirm_capable) {
1200                         flags |= TARGET_ASSIST_FLAGS_CONFIRMED;
1201                 }*/
1202         }
1203         TRACE_DBG("flags %x, tag %x, lun %x, offset %x, length %x",
1204                   flags, tag, lun, offset, length);
1205
1206         req->StatusCode = 0;
1207         req->TargetAssistFlags = (u8)flags;
1208         req->Function = MPI_FUNCTION_TARGET_ASSIST;
1209         req->QueueTag = (u16)tag;
1210         req->ReplyWord = cpu_to_le32(reply_word);
1211         req->LUN[0] = (u8)(lun >> 8);
1212         req->LUN[1] = (u8)lun;
1213         req->RelativeOffset = cpu_to_le32(offset);
1214         req->DataLength = cpu_to_le32(length);
1215         sge_flags =
1216                 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1217                                   MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1218         if (flags & TARGET_ASSIST_FLAGS_DATA_DIRECTION)
1219                 sge_flags |= MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_HOST_TO_IOC);
1220         sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
1221         for (i = 0, j = 0, k = 0; i < (int)sgl->num_sges; i++, j++) {
1222                 if (k == 0) {
1223                         /* still in mf, haven't chained yet -- do we need to? */
1224                         if (j == priv->num_sge_target_assist) {
1225                                 /* yes, we need to chain */
1226                                 /* overwrite the last element in the mf with a chain */
1227                                 sge_chain = (MPT_STM_CHAIN *)(sge_simple - 1);
1228                                 sge_chain->Flags =
1229                                         (u8)(MPI_SGE_FLAGS_CHAIN_ELEMENT |
1230                                                  MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1231                                 dma_addr = priv->hw_dma +
1232                                         ((u8 *)priv->hw->cmd_buf[index].chain_sge -
1233                                          (u8 *)priv->hw);
1234                                 stm_set_dma_addr(sge_chain->Address, dma_addr);
1235                                 /* set the "last element" flag in the mf */
1236                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain - 1);
1237                                 sge_simple->FlagsLength |=
1238                                         cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT));
1239                                 /* redo the last element in the mf */
1240                                 sge_simple =
1241                                         (MPT_STM_SIMPLE *)priv->hw->cmd_buf[index].chain_sge;
1242                                 sge_simple->FlagsLength =
1243                                         cpu_to_le32(sgl->sge[i-1].length | sge_flags);
1244                                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i-1].address);
1245                                 mpt_dump_sge(&sgl->sge[i-1], NULL);
1246                                 sge_simple++;
1247                                 /* say we've chained */
1248                                 req->ChainOffset =
1249                                         ((u8 *)sge_chain - (u8 *)req) / sizeof(u32);
1250                                 j = 1;
1251                                 k++;
1252                         }
1253                 } else {
1254                         /* now in chain, do we need to chain again? */
1255                         if (j == priv->num_sge_chain) {
1256                                 /* yes, we need to chain */
1257                                 /* fix up the previous chain element */
1258                                 chain_length = sizeof(MPT_STM_CHAIN) +
1259                                         (priv->num_sge_chain - 1) * sizeof(MPT_STM_SIMPLE);
1260                                 sge_chain->Length = cpu_to_le16(chain_length);
1261                                 sge_chain->NextChainOffset =
1262                                         (chain_length - sizeof(MPT_STM_CHAIN)) / sizeof(u32);
1263                                 /* overwrite the last element in the chain with another chain */
1264                                 sge_chain = (MPT_STM_CHAIN *)(sge_simple - 1);
1265                                 sge_chain->Flags =
1266                                         (u8)(MPI_SGE_FLAGS_CHAIN_ELEMENT |
1267                                                  MPI_SGE_FLAGS_MPT_STM_ADDRESSING);
1268                                 dma_addr = priv->hw_dma + ((u8 *)sge_simple - (u8 *)priv->hw);
1269                                 stm_set_dma_addr(sge_chain->Address, dma_addr);
1270                                 /* set the "last element" flag in the previous chain */
1271                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain - 1);
1272                                 sge_simple->FlagsLength |=
1273                                         cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT));
1274                                 /* redo the last element in the previous chain */
1275                                 sge_simple = (MPT_STM_SIMPLE *)(sge_chain + 1);
1276                                 sge_simple->FlagsLength =
1277                                         cpu_to_le32(sgl->sge[i-1].length | sge_flags);
1278                                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i-1].address);
1279                                 mpt_dump_sge(&sgl->sge[i-1], NULL);
1280                                 sge_simple++;
1281                                 /* say we've chained */
1282                                 j = 1;
1283                                 k++;
1284                         }
1285                 }
1286                 sge_simple->FlagsLength = cpu_to_le32(sgl->sge[i].length | sge_flags);
1287                 stm_set_dma_addr(sge_simple->Address, sgl->sge[i].address);
1288                 mpt_dump_sge(&sgl->sge[i], NULL);
1289                 sge_simple++;
1290         }
1291         /* did we chain? */
1292         if (k != 0) {
1293                 /* fix up the last chain element */
1294                 sge_chain->Length = cpu_to_le16(j * sizeof(MPT_STM_SIMPLE));
1295                 sge_chain->NextChainOffset = 0;
1296         }
1297         /* fix up the last element */
1298         sge_simple--;
1299         sge_simple->FlagsLength |=
1300                 cpu_to_le32(MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LAST_ELEMENT |
1301                                               MPI_SGE_FLAGS_END_OF_BUFFER |
1302                      MPI_SGE_FLAGS_END_OF_LIST));
1303 #ifdef TRACING
1304 if(trace_mpi)
1305 {
1306         u32 *p = (u32 *)req;
1307         int i;
1308         //dma_addr_t _data;
1309         //u8 *_buf;
1310
1311         TRACE(TRACE_MPI, "%s stm_send_target_data %d",
1312                         ioc->name, index);
1313         for (i = 0; i < (sizeof(*req) - sizeof(req->SGL)) / 4; i++) {
1314                 TRACE(TRACE_MPI, "%s req[%02x] = %08x",
1315                                 ioc->name, i * 4, le32_to_cpu(p[i]));
1316         }
1317         TRACE(TRACE_MPI, "%s num_sges = %d, j = %d, k = %d",
1318                         ioc->name, sgl->num_sges, j, k);
1319         p = (u32 *)&req->SGL;
1320         for (i = 0; i < ((k != 0) ? priv->num_sge_target_assist : j); i++) {
1321 #if MPT_STM_64_BIT_DMA
1322         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x %08x",
1323                                 ioc->name, i * 12, le32_to_cpu(p[i*3]),
1324                                 le32_to_cpu(p[i*3+1]), le32_to_cpu(p[i*3+2]));
1325 #else
1326         _data = le32_to_cpu(p[i*2+1]);
1327         _buf = (u8 *)phys_to_virt(_data);
1328         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x,%x,%x,%x,%x,%p",
1329                         ioc->name, i * 8, le32_to_cpu(p[i*2]), le32_to_cpu(p[i*2+1]),
1330                         _buf[0], _buf[1], _buf[2], _buf[3], _buf);
1331 #endif
1332         }
1333         p = (u32 *)priv->hw->cmd_buf[index].chain_sge;
1334         for (i = 0; i < ((k != 0) ? (k - 1) * priv->num_sge_chain + j : 0); i++) {
1335 #if MPT_STM_64_BIT_DMA
1336         TRACE(TRACE_MPI, "%s chain sgl[%04x] = %08x %08x %08x",
1337                         ioc->name, i * 12, le32_to_cpu(p[i*3]),
1338                         le32_to_cpu(p[i*3+1]), le32_to_cpu(p[i*3+2]));
1339 #else
1340         _data = le32_to_cpu(p[i*2+1]);
1341         _buf = (u8 *)phys_to_virt(_data);
1342         TRACE(TRACE_MPI, "%s req sgl[%04x] = %08x %08x,%x,%x,%x,%x,%p",
1343                         ioc->name, i * 8, le32_to_cpu(p[i*2]), le32_to_cpu(p[i*2+1]),
1344                         _buf[0], _buf[1], _buf[2], _buf[3], _buf);
1345 #endif
1346                 }
1347         }
1348 #endif
1349         res = 0;
1350
1351         priv->io_state[index] |= IO_STATE_DATA_SENT;
1352         if (flags & TARGET_ASSIST_FLAGS_AUTO_STATUS)
1353                 priv->io_state[index] |= IO_STATE_STATUS_SENT;
1354
1355
1356         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
1357                 res =mpt_send_handshake_request(stm_context, _IOC_ID,
1358                                            ioc->req_sz, (u32 *)req _HS_SLEEP);
1359         } else {
1360                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
1361         }
1362
1363         TRACE_EXIT_RES(res);
1364
1365         return res;
1366 }
1367
1368 /*
1369  * calling mpt_send_target_data
1370  *
1371  */
1372 static void
1373 mpt_send_target_data(struct mpt_prm *prm, int flags)
1374 {
1375         MPT_STM_PRIV *priv;
1376         u32 reply_word;
1377         int index, lun, tag, length, offset;
1378         MPT_SGL *sgl;
1379
1380         TRACE_ENTRY();
1381         priv = prm->tgt->priv;
1382         sgl = &priv->sgl;
1383
1384         mpt_sge_to_sgl(prm, priv, sgl);
1385
1386         reply_word = prm->cmd->CMD->reply_word;
1387         index = GET_IO_INDEX(reply_word);
1388
1389         lun = prm->cmd->CMD->lun;
1390         tag = prm->cmd->CMD->tag;
1391
1392         if (prm->data_direction == SCST_DATA_READ) {
1393                 flags |= TARGET_ASSIST_FLAGS_DATA_DIRECTION;
1394         }
1395
1396         length = prm->bufflen;
1397         offset = 0;
1398 #if 0
1399         TRACE_DBG("priv %p, reply_word %x, index %x, flags %x, lun %x, "
1400                   "tag %x, sgl %p, length %x, offset %x",
1401                   priv, reply_word, index, flags, lun, tag,
1402                   sgl, length, offset);
1403 #endif
1404         mpt_send_tgt_data(priv, reply_word, index, flags, lun, tag,
1405                         sgl, length, offset);
1406
1407         TRACE_EXIT();
1408         return;
1409 }
1410
1411 /*
1412  * this function checks if we need to handle REQUEST_SENSE on behalf of the
1413  * target device.  If the sense wasn't able to be sent simultaneously
1414  * with the status for the last command with a check condition, it needs
1415  * to either get sent for a REQUEST_SENSE command or forgotten.
1416  *
1417  * The pending_sense state and a buffer for holding sense is created for
1418  * each possible initiator.  The pending_sense state is used to tell if
1419  * sending sense failed and to track the progress of the following
1420  * REQUEST_SENSE command.
1421  *
1422  * There are four values for the pending_sense state:
1423  * - STATUS_SENSE_IDLE: no caching of sense data is in progress
1424  * - STATUS_SENSE_ATTEMPT: an attempt is being made to send status and
1425  *   sense in the same bus transaction.
1426  * - STATUS_SENSE_NOT_SENT: the attempt to send simultanous status and
1427  *   sense failed.
1428  * - STATUS_SENSE_HANDLE_RQ: the next command from the initiator needs
1429  *   to be handled by the LSI driver if it is REQUEST_SENSE using cached
1430  *   sense data, otherwise the cached sense data is ignored and the
1431  *   command is sent to SCST.
1432  *
1433  * In stmapp_pending_sense, if pending_sense state for an initiator ==
1434  * SENSE_HANDLE_RQ, the incoming command is inspected.  If it is
1435  * REQUEST_SENSE, the command is handled by the LSI driver without
1436  * involving SCST.  The cached sense data from the immediately previous
1437  * command is used.  This sense data was not sent along with the status
1438  * for that command (see below).  If the command is not REQUEST_SENSE,
1439  * the cached sense data is discarded and the command is sent to SCST
1440  * for processing.
1441  *
1442  * In stm_send_target_status, sense data about to be sent is saved in a
1443  * buffer and the pending_sense state for that initiator is set to
1444  * MPT_STATUS_SENSE_ATTEMPT.  The sense and status are sent to the LSI
1445  * hardware.
1446  *
1447  * If the LSI hardware determines that the sense and status could not be
1448  * sent in one operation, stm_reply is called with state == STATUS_SENT
1449  * and with IOCStatus of MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT (0x6B).
1450  * This condition only happens in the non-packetized SCSI operating mode.
1451  * When this happens, the pending_sense state is advanced to
1452  * MPT_STATUS_SENSE_NOT_SENT.
1453  *
1454  * In stm_tgt_reply, if io_state == STATUS_SENT:
1455  * - if pending_sense state == SENSE_ATTEMPT, the status and sense attempt was
1456  *   successful, so the pending_sense state is set to IDLE and the command
1457  *   is sent to SCST for completion.
1458  * - if pending_sense state == SENSE_NOT_SENT, the status and sense attempt
1459  *   failed.  The pending_sense state is advanced to SENSE_HANDLE_RQ and the
1460  *   current command is sent to SCST for completion.  The next command from
1461  *   this initiator will enter stmapp_pending_sense as described above.
1462  * - if pending_sense state == SENSE_HANDLE_RQ, the REQUEST_SENSE command
1463  *   handled alone by the LSI driver is done and resources need to be
1464  *   released.  pending_sense state is set to IDLE.
1465  * - if pending_sense state == SENSE_IDLE, a normal SCST command is done
1466  *   and is sent to SCST for completion.
1467  *
1468  * Because of this caching sense behaviour, we think we need to turn off
1469  * tagged command queueing.  The mpt_inquiry_no_tagged_commands function
1470  * does this by modifying INQUIRY data before sending it over the wire.
1471  */
1472 static int
1473 stmapp_pending_sense(struct mpt_cmd *mpt_cmd)
1474 {
1475         int res = 0;
1476         MPT_STM_PRIV *priv;
1477         int index = 0;
1478         int init_index = 0;
1479         int flags = 0;
1480         SCSI_CMD *scsi_cmd = NULL;
1481         CMD *cmd;
1482         u8 *cdb;
1483         struct mpt_prm prm = { 0 };
1484         struct scst_cmd *scst_cmd;
1485         struct scatterlist sg;
1486
1487         TRACE_ENTRY();
1488
1489         priv = mpt_cmd->priv;
1490         if (IsScsi(priv)) {
1491                 index = GET_IO_INDEX(mpt_cmd->reply_word);
1492                 init_index = GET_INITIATOR_INDEX(mpt_cmd->reply_word);
1493                 if (atomic_read(&priv->pending_sense[init_index]) ==
1494                                 MPT_STATUS_SENSE_HANDLE_RQ) {
1495                         cmd = &priv->hw->cmd_buf[index];
1496                         scsi_cmd = (SCSI_CMD *)cmd->cmd;
1497                         cdb = scsi_cmd->CDB;
1498
1499                         if (cdb[0] == REQUEST_SENSE) {
1500                                 /* scst_cmd used as a container in stm_tgt_reply,
1501                                  * command doesn't actually go to SCST */
1502                                 scst_cmd = kmalloc(sizeof(struct scst_cmd),
1503                                                 GFP_ATOMIC);
1504                                 TRACE_DBG("scst_cmd 0x%p", scst_cmd);
1505                                 if (scst_cmd != NULL) {
1506                                         cmd->reply_word = mpt_cmd->reply_word;
1507                                         if (cmd->reply_word &
1508                                                 TARGET_MODE_REPLY_ALIAS_MASK) {
1509                                                 cmd->alias = (scsi_cmd->AliasID -
1510                                                                 priv->port_id) & 15;
1511                                         } else {
1512                                                 cmd->alias = 0;
1513                                         }
1514                                         cmd->lun = get2bytes(scsi_cmd->LogicalUnitNumber,
1515                                                         0);
1516                                         cmd->tag = scsi_cmd->Tag;
1517                                         mpt_cmd->CMD = cmd;
1518
1519                                         memset(scst_cmd, 0x00,
1520                                                 sizeof(struct scst_cmd));
1521                                         scst_cmd->resp_data_len = -1;
1522                                         memcpy(scst_cmd->cdb, cdb,
1523                                                         MPT_MAX_CDB_LEN);
1524                                         priv->scst_cmd[index] = scst_cmd;
1525                                         scst_cmd_set_tag(scst_cmd, cmd->tag);
1526                                         scst_cmd_set_tgt_priv(scst_cmd, mpt_cmd);
1527
1528                                         TRACE_BUFFER("CDB", cdb, MPT_MAX_CDB_LEN);
1529
1530                                         flags = TARGET_ASSIST_FLAGS_AUTO_STATUS;
1531                                         prm.cmd = mpt_cmd;
1532                                         /* smallest amount of data between
1533                                          * requested length, buffer size,
1534                                          * and cached length */
1535                                         prm.bufflen = min((size_t)cdb[4],
1536                                                 (size_t)SCSI_SENSE_BUFFERSIZE);
1537                                         prm.bufflen = min(prm.bufflen,
1538                                                 (size_t)(priv->pending_sense_buffer[init_index][7]
1539                                                          + 8));
1540                                         sg_set_page(&sg,
1541                                                 virt_to_page(priv->pending_sense_buffer[init_index]),
1542                                                 prm.bufflen,
1543                                                 offset_in_page(priv->pending_sense_buffer[init_index]));
1544                                         prm.buffer = &sg;
1545                                         prm.use_sg = 1;
1546                                         prm.data_direction = SCST_DATA_READ;
1547                                         prm.tgt = priv->tgt->sess[init_index]->tgt;
1548                                         prm.cmd->state = MPT_STATE_DATA_OUT;
1549
1550                                         TRACE_DBG("%s: sending pending sense",
1551                                                         priv->ioc->name);
1552                                         mpt_send_target_data(&prm, flags);
1553                                         res = 1;
1554                                 } else {
1555                                         /* we couldn't create a scst_cmd, so
1556                                          * we can't do anything.  Send the
1557                                          * command to SCST. */
1558                                         atomic_set(&priv->pending_sense[init_index],
1559                                                         MPT_STATUS_SENSE_IDLE);
1560                                 }
1561                         } else {
1562                                 /* next command immediately after check
1563                                  * condition is not REQUEST_SENSE, so we can
1564                                  * discard the cached sense and send the
1565                                  * command to SCST. */
1566                                 atomic_set(&priv->pending_sense[init_index],
1567                                                 MPT_STATUS_SENSE_IDLE);
1568                         }
1569                 } else {
1570                         /* we don't need to perform REQUEST_SENSE and can
1571                          * send the command to SCST */
1572                         atomic_set(&priv->pending_sense[init_index],
1573                                         MPT_STATUS_SENSE_IDLE);
1574                 }
1575         }
1576
1577         TRACE_EXIT_RES(res);
1578         return res;
1579 }
1580
1581 /*
1582  * this function is equivalent to the SCSI queuecommand(). The target should
1583  * transmit the response data and the status in the struct scst_cmd. See
1584  * below for details. Must be defined.
1585  */
1586 static int
1587 mpt_xmit_response(struct scst_cmd *scst_cmd)
1588 {
1589         int res = SCST_TGT_RES_SUCCESS;
1590         struct mpt_sess *sess;
1591         struct mpt_prm prm = { 0 };
1592         int is_send_status;
1593         //uint16_t full_req_cnt;
1594         //int data_sense_flag = 0;
1595
1596         TRACE_ENTRY();
1597
1598 #ifdef DEBUG_WORK_IN_THREAD
1599         if (scst_cmd_atomic(scst_cmd))
1600                 return SCST_TGT_RES_NEED_THREAD_CTX;
1601 #endif
1602
1603         prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1604         sess = (struct mpt_sess *)
1605                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
1606
1607         prm.sg = NULL;
1608         prm.bufflen = scst_cmd_get_resp_data_len(scst_cmd);
1609         prm.buffer = scst_cmd->sg;
1610         prm.use_sg = scst_cmd->sg_cnt;
1611         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
1612         prm.rq_result = scst_cmd_get_status(scst_cmd);
1613         prm.sense_buffer = scst_cmd_get_sense_buffer(scst_cmd);
1614         prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
1615         prm.tgt = sess->tgt;
1616         prm.seg_cnt = 0;
1617         is_send_status = scst_cmd_get_is_send_status(scst_cmd);
1618
1619         TRACE_DBG("rq_result=%x, is_send_status=%x, %x, %d", prm.rq_result,
1620                         is_send_status, prm.bufflen, prm.sense_buffer_len);
1621         if ((prm.rq_result != 0) && (prm.sense_buffer != NULL))
1622                 TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
1623
1624         if (!is_send_status) {
1625                 /* ToDo, after it's done in SCST */
1626                 PRINT_ERROR(MYNAM ": is_send_status not set: "
1627                             "feature not implemented %p", scst_cmd);
1628                 res = SCST_TGT_RES_FATAL_ERROR;
1629                 goto out_tgt_free;
1630         }
1631
1632         if (test_bit(MPT_SESS_SHUTDOWN, &sess->sess_flags)) {
1633                 TRACE_DBG("cmd %p while session %p is shutting down",
1634                           prm.cmd, sess);
1635                 res = SCST_TGT_RES_SUCCESS;
1636                 goto out_tgt_free;
1637         }
1638
1639         if (SCST_SENSE_VALID(prm.sense_buffer)) {
1640                 mpt_set_sense_info(prm.tgt->priv, prm.cmd->CMD,
1641                                 prm.sense_buffer_len, prm.sense_buffer);
1642         }
1643
1644         if (scst_cmd_get_resp_data_len(scst_cmd) > 0) {
1645                 int flags = 0;
1646                 if (prm.rq_result == 0) {
1647                         flags |= TARGET_ASSIST_FLAGS_AUTO_STATUS;
1648                 }
1649                 if (scst_get_may_need_dma_sync(scst_cmd)) {
1650                         dma_sync_sg(&(prm.tgt->priv->ioc->pcidev->dev),
1651                                 scst_cmd->sg, scst_cmd->sg_cnt,
1652                                 scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
1653                 }
1654                 mpt_send_target_data(&prm, flags);
1655
1656                 if (prm.rq_result == 0) {
1657                         goto out;
1658                 }
1659         }
1660         {
1661                 int flags = 0;
1662                 u32 reply_word = prm.cmd->CMD->reply_word;
1663                 int index = GET_IO_INDEX(reply_word);
1664                 int lun = prm.cmd->CMD->lun;
1665                 int tag = prm.cmd->CMD->tag;
1666                 MPT_STM_PRIV *priv = prm.tgt->priv;
1667
1668                 if (prm.rq_result == 0) {
1669                         flags |= TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS;
1670                 }
1671
1672                 flags |= TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
1673                 priv->io_state[index] |= IO_STATE_AUTO_REPOST;
1674
1675                 TRACE_DBG("scst cmd %p, index %d, flags %d",
1676                                 scst_cmd, index, flags);
1677
1678                 stm_send_target_status(priv, reply_word, index,
1679                                 flags, lun, tag);
1680         }
1681
1682  out:
1683         TRACE_EXIT_RES(res);
1684
1685         return res;
1686
1687  out_tgt_free:
1688         /* ToDo: check and set scst_set_delivery_status(), if necessary */
1689         scst_tgt_cmd_done(scst_cmd);
1690         goto out;
1691 }
1692
1693 /*
1694  * modifiy the response for an INQUIRY command to turn off
1695  * support for tagged command queuing if we're on a SCSI bus.
1696  * It's doubtful that caching sense data will work correctly
1697  * if tagging is enabled.
1698  */
1699 static void
1700 mpt_inquiry_no_tagged_commands(MPT_STM_PRIV *priv, struct scst_cmd *scst_cmd)
1701 {
1702         int32_t length;
1703         uint8_t *address;
1704
1705         TRACE_ENTRY();
1706
1707         /*
1708          * only modify INQUIRY if we're on a SCSI bus,
1709          * and we are handling a standard INQUIRY command
1710          * (EVPD = 0)
1711          */
1712         if (IsScsi(priv) && (scst_cmd->cdb[0] == INQUIRY) &&
1713                         !(scst_cmd->cdb[1] & 0x1)) {
1714                 sBUG_ON(scst_cmd->sg_cnt == 0);
1715                 length = scst_get_buf_first(scst_cmd, &address);
1716                 if (length >= 8) {
1717                         TRACE_DBG("clearing BQUE + CMDQUE 0x%p", address);
1718                         address[6] &= ~0x80; /* turn off BQUE */
1719                         address[7] &= ~0x02; /* turn off CMDQUE */
1720                 }
1721                 scst_put_buf(scst_cmd, address);
1722         }
1723
1724         TRACE_EXIT();
1725 }
1726
1727 /*
1728  * this function
1729  * informs the driver that data buffer corresponding to the said command
1730  * have now been allocated and it is OK to receive data for this command.
1731  * This function is necessary because a SCSI target does not have any
1732  * control over the commands it receives. Most lower-level protocols have a
1733  * corresponding function which informs the initiator that buffers have
1734  * been allocated e.g., XFER_RDY in Fibre Channel. After the data is
1735  * actually received the low-level driver should call scst_rx_data()
1736  * in order to continue processing this command. Returns one of the
1737  * SCST_TGT_RES_* constants, described below. Pay attention to
1738  * "atomic" attribute of the command, which can be get via
1739  * scst_cmd_get_atomic(): it is true if the function called in the
1740  * atomic (non-sleeping) context. Must be defined.
1741  */
1742 static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd)
1743 {
1744         int res = SCST_TGT_RES_SUCCESS;
1745         struct mpt_sess *sess;
1746         /*unsigned long flags = 0;*/
1747         struct mpt_prm prm = { 0 };
1748
1749         TRACE_ENTRY();
1750
1751 #ifdef DEBUG_WORK_IN_THREAD
1752         if (scst_cmd_atomic(scst_cmd))
1753                 return SCST_TGT_RES_NEED_THREAD_CTX;
1754 #endif
1755
1756         prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1757         sess = (struct mpt_sess *)
1758                 scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
1759         mpt_inquiry_no_tagged_commands(sess->tgt->priv, scst_cmd);
1760
1761         prm.sg = (struct scatterlist *)NULL;
1762         prm.bufflen = scst_cmd->bufflen;
1763         prm.buffer = scst_cmd->sg;
1764         prm.use_sg = scst_cmd->sg_cnt;
1765         prm.data_direction = scst_cmd_get_data_direction(scst_cmd);
1766         prm.tgt = sess->tgt;
1767
1768         if (test_bit(MPT_SESS_SHUTDOWN, &sess->sess_flags)) {
1769                 TRACE_DBG("cmd %p while session %p is shutting down",
1770                           prm.cmd, sess);
1771                 scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_FATAL,
1772                              SCST_CONTEXT_THREAD);
1773                 res = SCST_TGT_RES_SUCCESS;
1774                 goto out;
1775         }
1776
1777         prm.cmd->state = MPT_STATE_NEED_DATA;
1778
1779         mpt_send_target_data(&prm, 0);
1780
1781  out:
1782         TRACE_EXIT_RES(res);
1783
1784         return res;
1785 }
1786
1787 /*
1788  * this function
1789  * called to notify the driver that the command is about to be freed.
1790  * Necessary, because for aborted commands <bf/xmit_response()/ could not be
1791  * called. Could be used on IRQ context. Must be defined.
1792  */
1793 static void mpt_on_free_cmd(struct scst_cmd *scst_cmd)
1794 {
1795         struct mpt_cmd *cmd =
1796                 (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
1797
1798         TRACE_ENTRY();
1799
1800         TRACE_DBG("cmd %p, scst_cmd %p", cmd, scst_cmd);
1801
1802         scst_cmd_set_tgt_priv(scst_cmd, NULL);
1803
1804 #if 1
1805         memset(cmd, 0, sizeof(*cmd));
1806 #endif
1807         kfree(cmd);
1808
1809         TRACE_EXIT();
1810 }
1811
1812 /*
1813  * this function informs the driver that a received task management
1814  * function has been completed. Completion status could be get via
1815  * scst_mgmt_cmd_get_status(). No return value expected. Must be
1816  * defined, if the target supports task management functionality.
1817  */
1818 static void
1819 mpt_task_mgmt_fn_done(struct scst_mgmt_cmd *mgmt_cmd)
1820 {
1821         TRACE_ENTRY();
1822         WARN_ON(1);
1823         TRACE_EXIT();
1824 }
1825
1826 static void
1827 mpt_local_task_mgmt(struct mpt_sess *sess, int task_mgmt, int lun)
1828 {
1829         struct mpt_cmd *cmd, *t;
1830
1831         TRACE_ENTRY();
1832         switch (task_mgmt) {
1833         case IMM_NTFY_TARGET_RESET:
1834                 while (!list_empty(&sess->delayed_cmds)) {
1835                         cmd = list_entry(sess->delayed_cmds.next,
1836                                          typeof(*cmd), delayed_cmds_entry);
1837                         list_del(&cmd->delayed_cmds_entry);
1838                         kfree(cmd);
1839                 }
1840                 break;
1841
1842         case IMM_NTFY_LUN_RESET1:
1843         case IMM_NTFY_LUN_RESET2:
1844         case IMM_NTFY_CLEAR_TS:
1845         case IMM_NTFY_ABORT_TS:
1846                 list_for_each_entry_safe(cmd, t, &sess->delayed_cmds,
1847                                          delayed_cmds_entry)
1848                         {
1849                                 if (cmd->CMD->lun == lun) {
1850                                         list_del(&cmd->delayed_cmds_entry);
1851                                         kfree(cmd);
1852                                 }
1853                         }
1854                 break;
1855
1856         case IMM_NTFY_CLEAR_ACA:
1857         default:
1858                 break;
1859         }
1860         TRACE_EXIT();
1861 }
1862
1863 static int
1864 mpt_handle_task_mgmt(MPT_STM_PRIV *priv, u32 reply_word,
1865                      int task_mgmt, int _lun)
1866 {
1867         int res = 0, rc = 0;
1868         struct mpt_mgmt_cmd *mcmd;
1869         struct mpt_tgt *tgt;
1870         struct mpt_sess *sess;
1871         int init_index;
1872         uint16_t lun = _lun;
1873
1874         TRACE_ENTRY();
1875
1876         TRACE_DBG("task_mgmt %d", task_mgmt);
1877         tgt = priv->tgt;
1878         init_index = GET_INITIATOR_INDEX(reply_word);
1879
1880         sess = tgt->sess[init_index];
1881         if (sess == NULL) {
1882                 TRACE(TRACE_MGMT, "mpt_scst(%s): task mgmt fn %p for "
1883                       "unexisting session", priv->ioc->name, tgt);
1884                 res = -EFAULT;
1885                 goto out;
1886         }
1887
1888         if (test_bit(MPT_SESS_INITING, &sess->sess_flags)) {
1889                 TRACE(TRACE_MGMT, "mpt_scst(%s): task mgmt fn %p for "
1890                       "inited session", priv->ioc->name, tgt);
1891                 mpt_local_task_mgmt(sess, reply_word, task_mgmt);
1892                 res = -EFAULT;
1893                 goto out;
1894         }
1895
1896         mcmd = kmalloc(sizeof(*mcmd), GFP_ATOMIC);
1897         TRACE_MEM("kmalloc(GFP_ATOMIC) for mcmd (%d): %p",
1898                   sizeof(*mcmd), mcmd);
1899         if (mcmd == NULL) {
1900                 TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of mgmt cmd failed");
1901                 res = -ENOMEM;
1902                 goto out;
1903         }
1904
1905         memset(mcmd, 0, sizeof(*mcmd));
1906         mcmd->sess = sess;
1907         mcmd->task_mgmt = task_mgmt;
1908
1909         switch(task_mgmt) {
1910         case IMM_NTFY_CLEAR_ACA:
1911                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_ACA received");
1912                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_ACA,
1913                                          (uint8_t *)&lun, sizeof(lun),
1914                                          SCST_ATOMIC, mcmd);
1915                 break;
1916         case IMM_NTFY_TARGET_RESET:
1917                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_TARGET_RESET received");
1918                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
1919                                          (uint8_t *)&lun, sizeof(lun),
1920                                          SCST_ATOMIC, mcmd);
1921                 break;
1922         case IMM_NTFY_LUN_RESET1:
1923         case IMM_NTFY_LUN_RESET2:
1924                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_LUN_RESET received");
1925                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
1926                                          (uint8_t *)&lun, sizeof(lun),
1927                                          SCST_ATOMIC, mcmd);
1928                 break;
1929         case IMM_NTFY_CLEAR_TS:
1930                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_CLEAR_TS received");
1931                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_CLEAR_TASK_SET,
1932                                          (uint8_t *)&lun, sizeof(lun),
1933                                          SCST_ATOMIC, mcmd);
1934                 break;
1935
1936         case IMM_NTFY_ABORT_TS:
1937                 TRACE(TRACE_MGMT, "%s", "IMM_NTFY_ABORT_TS received");
1938                 rc = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_ABORT_TASK_SET,
1939                                          (uint8_t *)&lun, sizeof(lun),
1940                                          SCST_ATOMIC, mcmd);
1941                 break;
1942
1943         default:
1944                 PRINT_ERROR("mpt_scst(%s): Unknown task mgmt fn 0x%x",
1945                             priv->ioc->name, task_mgmt);
1946                 break;
1947         }
1948         if (rc != 0) {
1949                 PRINT_ERROR("mpt_scst(%s): scst_rx_mgmt_fn_lun() failed: %d",
1950                             priv->ioc->name, rc);
1951                 res = -EFAULT;
1952                 goto out_free;
1953         }
1954
1955  out:
1956         TRACE_EXIT_RES(res);
1957         return res;
1958
1959  out_free:
1960         TRACE_MEM("kmem_cache_free for mcmd %p", mcmd);
1961         kfree(mcmd);
1962         goto out;
1963 }
1964
1965
1966
1967 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1968 /*
1969  *  called when any target mode reply is received
1970  *  if mf_req is null, then this is a turbo reply; otherwise it's not
1971  */
1972 static int
1973 stm_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf_req, MPT_FRAME_HDR *mf_rep)
1974 {
1975     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
1976     MPIDefaultReply_t   *rep = (MPIDefaultReply_t *)mf_rep;
1977     int ioc_status;
1978
1979         TRACE_ENTRY();
1980         if (mf_req == NULL) {
1981                 TRACE_DBG("%s: got turbo reply, reply %x",
1982                                 ioc->name, CAST_PTR_TO_U32(mf_rep));
1983                 /*
1984                  *  this is a received SCSI command, so go handle it
1985                  */
1986                 stm_tgt_reply(ioc, CAST_PTR_TO_U32(mf_rep));
1987                 return 0;
1988         }
1989
1990 #if 0
1991     if (rep->Function == MPI_FUNCTION_EVENT_NOTIFICATION) {
1992         /*
1993          *  this is an event notification -- do nothing for now
1994          *  (this short-cuts the switch() below and avoids the printk)
1995          */
1996         return (0);
1997     }
1998 #endif
1999     ioc_status = le16_to_cpu(rep->IOCStatus);
2000
2001     TRACE_DBG("%s: request %p, reply %p (%02x), %d",
2002               ioc->name, mf_req, mf_rep, rep->Function, ioc_status);
2003     TRACE_DBG("%s: mf index = %d", ioc->name, MF_TO_INDEX(mf_req));
2004
2005         if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
2006                 TRACE_DBG("%s Function = %02x, IOCStatus = %04x, IOCLogInfo = %08x",
2007                                 ioc->name, rep->Function, ioc_status,
2008                                 le32_to_cpu(rep->IOCLogInfo));
2009         }
2010
2011     ioc_status &= MPI_IOCSTATUS_MASK;
2012     switch (rep->Function) {
2013         case MPI_FUNCTION_CONFIG:
2014             /*
2015              *  this signals that the config is done
2016              */
2017             priv->config_pending = 0;
2018             memcpy(&priv->config_rep, rep, sizeof(ConfigReply_t));
2019             /*
2020              *  don't free the message frame, since we're remembering it
2021              *  in priv->config_mf, and we'll be using it over and over
2022              */
2023             return (0);
2024
2025         case MPI_FUNCTION_PORT_ENABLE:
2026             /*
2027              *  this signals that the port enable is done
2028              */
2029             priv->port_enable_loginfo = le32_to_cpu(rep->IOCLogInfo);
2030             priv->port_enable_pending = 0;
2031             return (1);
2032
2033         case MPI_FUNCTION_TARGET_CMD_BUFFER_POST:
2034         case MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST:
2035             /*
2036              *  this is the response to a command buffer post; if status
2037              *  is success, then this just acknowledges the posting of a
2038              *  command buffer, so do nothing
2039              *
2040              *  we can also get here for High Priority I/O (such as getting
2041              *  a command while not being allowed to disconnect from the SCSI
2042              *  bus), and if we're shutting down
2043              */
2044                 if (ioc_status == MPI_IOCSTATUS_SUCCESS) {
2045                         TRACE_EXIT();
2046                         return 1;
2047                 }
2048                 if (priv->target_mode_abort_pending &&
2049                                 ioc_status == MPI_IOCSTATUS_TARGET_ABORTED) {
2050                         TRACE_EXIT();
2051                         return (0);
2052                 }
2053                 if (ioc_status == MPI_IOCSTATUS_TARGET_PRIORITY_IO) {
2054                         stm_tgt_reply_high_pri(ioc,
2055                                         (TargetCmdBufferPostErrorReply_t *)rep);
2056                         TRACE_EXIT();
2057                         return (0);
2058                 }
2059                 TRACE_DBG(":%s TargetCmdBufPostReq IOCStatus = %04x",
2060                                 ioc->name, ioc_status);
2061                 if (ioc_status == MPI_IOCSTATUS_INSUFFICIENT_RESOURCES) {
2062                         /*
2063                          *  this should never happen since we carefully count
2064                          *  our resources, but if it does, tolerate it -- don't
2065                          *  repost the errant command buffer, lest we create an
2066                          *  endless loop
2067                          */
2068                         WARN_ON(1);
2069                         return (0);
2070                 }
2071                 if (ioc_status == MPI_IOCSTATUS_TARGET_NO_CONNECTION) {
2072                         printk(KERN_ERR MYNAM
2073                                         ": %s: Got MPI_IOCSTATUS_TARGET_NO_CONNECTION\n",
2074                                         ioc->name);
2075                         return (0);
2076                 }
2077                 if (rep->MsgLength > sizeof(*rep)/sizeof(u32)) {
2078                         TRACE_DBG("MsgLength is %d, %d",
2079                                         rep->MsgLength, sizeof(*rep)/sizeof(u32));
2080                         WARN_ON(1);
2081                         /*
2082                          *  the TargetCmdBufferPostErrorReply and TargetErrorReply
2083                          *  structures are nearly identical; the exception is that
2084                          *  the former does not have a TransferCount field, while
2085                          *  the latter does; add one
2086                          */
2087                         ((TargetErrorReply_t *)rep)->TransferCount = 0;
2088                         stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2089                         return (0);
2090                 }
2091                 WARN_ON(1);
2092             return (1);
2093
2094         case MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST:
2095             /*
2096              *  this signals that the command buffer base post is done
2097              */
2098             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2099                 printk(KERN_ERR MYNAM ":%s TargetCmdBufPostBaseReq IOCStatus = %04x\n",
2100                        ioc->name, ioc_status);
2101             }
2102             return (1);
2103
2104         case MPI_FUNCTION_TARGET_ASSIST:
2105             /*
2106              *  this is the response to a target assist command; we should
2107              *  only get here if an error occurred
2108              *
2109              *  at this point we need to clean up the remains of the I/O
2110              *  and repost the command buffer
2111              */
2112             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2113                 printk(KERN_ERR MYNAM ":%s TargetAssistReq IOCStatus = %04x\n",
2114                        ioc->name, ioc_status);
2115             }
2116             stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2117             return (0);
2118
2119         case MPI_FUNCTION_TARGET_STATUS_SEND:
2120             /*
2121              *  this is the response to a target status send command; we should
2122              *  only get here if an error occurred
2123              *
2124              *  at this point we need to clean up the remains of the I/O
2125              *  and repost the command buffer
2126              */
2127             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2128                 /* if this is a MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
2129                  * and we're SCSI, only print if we're debugging and
2130                  * tracing.  This is a normal consequence of attempting
2131                  * to send sense data and status in the same
2132                  * transaction.
2133                  */
2134                 if (IsScsi(priv) &&
2135                         (ioc_status == MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT)) {
2136                         TRACE_DBG(MYNAM ":%s TargetStatusSendReq IOCStatus = %04x\n",
2137                                 ioc->name, ioc_status);
2138                 } else {
2139                         printk(KERN_ERR MYNAM ":%s TargetStatusSendReq IOCStatus = %04x\n",
2140                                 ioc->name, ioc_status);
2141                 }
2142             }
2143             stm_target_reply_error(ioc, (TargetErrorReply_t *)rep);
2144             return (0);
2145
2146         case MPI_FUNCTION_TARGET_MODE_ABORT: {
2147             TargetModeAbort_t           *req = (TargetModeAbort_t *)mf_req;
2148
2149             /*
2150              *  this signals that the target mode abort is done
2151              */
2152             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2153                 printk(KERN_ERR MYNAM ":%s TargetModeAbort IOCStatus = %04x\n",
2154                        ioc->name, ioc_status);
2155             }
2156             if (req->AbortType == TARGET_MODE_ABORT_TYPE_ALL_CMD_BUFFERS) {
2157                 priv->target_mode_abort_pending = 0;
2158             } else {
2159                 u32             reply_word;
2160                 int             index;
2161                 volatile int    *io_state;
2162
2163                 /*
2164                  *  a target mode abort has finished, so check to see if
2165                  *  the I/O was aborted, but there was no error reply for
2166                  *  that aborted I/O (this will be the case for I/Os that
2167                  *  have no outstanding target assist or target status send
2168                  *  at the time of the abort request) -- so pretend that
2169                  *  the error reply came in with a status indicating that
2170                  *  the I/O was aborted
2171                  */
2172                 reply_word = le32_to_cpu(req->ReplyWord);
2173                 index = GET_IO_INDEX(reply_word);
2174                 io_state = priv->io_state + index;
2175                 if ((*io_state & IO_STATE_ABORTED) &&
2176                     !(*io_state & IO_STATE_DATA_SENT) &&
2177                     !(*io_state & IO_STATE_STATUS_SENT)) {
2178                     stmapp_target_error(priv, reply_word, index,
2179                                         MPI_IOCSTATUS_TARGET_ABORTED, 0);
2180                 }
2181                 /*
2182                 *  see if we were trying to abort a target assist or target
2183                 *  status send, but the abort didn't work (if the abort had
2184                 *  worked, the flag we're checking would be clear) -- if so,
2185                 *  just clear the various SRR flags, and wait for the initiator
2186                 *  to retry the SRR
2187                 */
2188                 if (*io_state & IO_STATE_REQUEST_ABORTED) {
2189                     printk(KERN_ERR MYNAM ":%s index %d: io_state = %x\n",
2190                            ioc->name, index, *io_state);
2191                     printk(KERN_ERR MYNAM ":%s   request was not aborted\n",
2192                            ioc->name);
2193                     *io_state &= ~IO_STATE_REQUEST_ABORTED;
2194                     *io_state &= ~IO_STATE_REISSUE_REQUEST;
2195                     *io_state &= ~IO_STATE_ADJUST_OFFSET;
2196                     *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2197                     *io_state &= ~IO_STATE_REDO_COMMAND;
2198                 }
2199             }
2200                 TRACE_EXIT_RES(1);
2201             return (1);
2202         }
2203
2204         case MPI_FUNCTION_FC_LINK_SRVC_BUF_POST:
2205             /*
2206              *  if the length is that of a default reply, then this is the
2207              *  response to a link service buffer post -- do nothing except
2208              *  report errors (none are expected); otherwise this is a
2209              *  received ELS, so go handle it
2210              */
2211             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2212                 if (priv->link_serv_abort_pending &&
2213                     ioc_status == MPI_IOCSTATUS_FC_ABORTED) {
2214                     return (0);
2215                 }
2216                 printk(KERN_ERR MYNAM ":%s FcLinkServBufPostReq IOCStatus = %04x\n",
2217                        ioc->name, ioc_status);
2218             }
2219             if (rep->MsgLength > sizeof(*rep)/sizeof(u32)) {
2220                 stm_link_service_reply(ioc,
2221                                        (LinkServiceBufferPostReply_t *)rep);
2222                 return (0);
2223             }
2224             return (1);
2225
2226         case MPI_FUNCTION_FC_LINK_SRVC_RSP:
2227             /*
2228              *  this is the response to a link service send -- repost the
2229              *  link service command buffer
2230              */
2231             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2232                 printk(KERN_ERR MYNAM ":%s FcLinkServRspReq IOCStatus = %04x\n",
2233                        ioc->name, ioc_status);
2234             }
2235             stm_link_service_rsp_reply(ioc,
2236                                        (LinkServiceRspRequest_t *)mf_req,
2237                                        (LinkServiceRspReply_t *)mf_rep);
2238             return (1);
2239
2240         case MPI_FUNCTION_FC_ABORT:
2241             /*
2242              *  this signals that the target mode abort is done
2243              */
2244             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2245                 printk(KERN_ERR MYNAM ":%s FcAbort IOCStatus = %04x\n",
2246                        ioc->name, ioc_status);
2247             }
2248             priv->link_serv_abort_pending = 0;
2249             return (1);
2250
2251         case MPI_FUNCTION_FC_PRIMITIVE_SEND:
2252             /*
2253              *  this signals that the FC primitive send is done
2254              */
2255             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2256                 printk(KERN_ERR MYNAM ":%s FcPrimitiveSend IOCStatus = %04x\n",
2257                        ioc->name, ioc_status);
2258             }
2259             priv->fc_primitive_send_pending = 0;
2260             return (1);
2261
2262         case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
2263             /*
2264              *  this signals that the extended link service send is done
2265              */
2266             if (ioc_status != MPI_IOCSTATUS_SUCCESS) {
2267                 printk(KERN_ERR MYNAM ":%s ExLinkServiceSend IOCStatus = %04x\n",
2268                        ioc->name, ioc_status);
2269             }
2270             priv->ex_link_service_send_pending = 0;
2271             return (1);
2272
2273         default:
2274             /*
2275              *  don't understand this reply, so dump to the screen
2276              */
2277             printk(KERN_ERR MYNAM ":%s got a reply (function %02x) that "
2278                    "I don't know what to do with\n", ioc->name, rep->Function);
2279 if(1)
2280 {
2281             u32 *p = (u32 *)mf_req;
2282             int i;
2283
2284             for (i = 0; i < 16; i++) {
2285                 printk("%s mf_req[%02x] = %08x\n",
2286                        ioc->name, i * 4, le32_to_cpu(p[i]));
2287             }
2288 }
2289 if(1)
2290 {
2291             u32 *p = (u32 *)mf_rep;
2292             int i;
2293
2294             for (i = 0; i < 16; i++) {
2295                 printk("%s mf_rep[%02x] = %08x\n",
2296                        ioc->name, i * 4, le32_to_cpu(p[i]));
2297             }
2298 }
2299             break;
2300     }
2301         TRACE_EXIT();
2302     return (0);
2303 }
2304
2305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2306 static void
2307 stm_tgt_reply_high_pri(MPT_ADAPTER *ioc, TargetCmdBufferPostErrorReply_t *rep)
2308 {
2309         MPT_STM_PRIV    *priv = mpt_stm_priv[ioc->id];
2310         u32                     reply_word;
2311         int                     reason;
2312         int                     index;
2313
2314         TRACE_ENTRY();
2315         reply_word = le32_to_cpu(rep->ReplyWord);
2316         reason = rep->PriorityReason;
2317
2318         index = GET_IO_INDEX(reply_word);
2319
2320         TRACE_DBG("%s: target reply high priority", ioc->name);
2321         TRACE_DBG("%s: ReplyWord = %08x, PriorityReason = %02x",
2322                         ioc->name, reply_word, reason);
2323
2324         priv->io_state[index] |= IO_STATE_HIGH_PRIORITY;
2325         if (reason == PRIORITY_REASON_NO_DISCONNECT ||
2326                         reason == PRIORITY_REASON_SCSI_TASK_MANAGEMENT) {
2327                 stm_tgt_reply(ioc, reply_word);
2328                 goto out;
2329         }
2330
2331         WARN_ON(1);
2332         if (reason == PRIORITY_REASON_TARGET_BUSY) {
2333                 CMD             *cmd;
2334                 int             lun;
2335                 int             tag;
2336
2337                 priv->io_state[index] &= ~IO_STATE_POSTED;
2338                 cmd = priv->hw->cmd_buf + index;
2339                 if (IsScsi(priv)) {
2340                         SCSI_CMD        *scsi_cmd = (SCSI_CMD *)cmd->cmd;
2341
2342                         lun = get2bytes(scsi_cmd->LogicalUnitNumber, 0);
2343                         tag = scsi_cmd->Tag;
2344                 } else if (IsSas(priv)) {
2345                         SSP_CMD *ssp_cmd = (SSP_CMD *)cmd->cmd;
2346
2347                         lun = get2bytes(ssp_cmd->LogicalUnitNumber, 0);
2348                         tag = ssp_cmd->InitiatorTag;
2349                 } else {
2350                         FCP_CMD *fcp_cmd = (FCP_CMD *)cmd->cmd;
2351
2352                         lun = get2bytes(fcp_cmd->FcpLun, 0);
2353                         tag = 0;
2354                 }
2355                 memset(cmd->rsp, 0, sizeof(cmd->rsp));
2356                 stmapp_set_status(priv, cmd, STS_TASK_SET_FULL);
2357                 stm_send_target_status(priv, reply_word, index, 0, lun, tag);
2358         } else {
2359                 stmapp_target_error(priv, reply_word, index,
2360                                 MPI_IOCSTATUS_TARGET_PRIORITY_IO, reason);
2361         }
2362 out:
2363         TRACE_EXIT();
2364 }
2365
2366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2367 static void
2368 stm_target_reply_error(MPT_ADAPTER *ioc,
2369                        TargetErrorReply_t *rep)
2370 {
2371     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2372     u32                 reply_word;
2373     int                 index;
2374     int                 status;
2375     int                 reason;
2376     volatile int        *io_state;
2377
2378         TRACE_ENTRY();
2379     reply_word = le32_to_cpu(rep->ReplyWord);
2380     status = le16_to_cpu(rep->IOCStatus) & MPI_IOCSTATUS_MASK;
2381
2382     index = GET_IO_INDEX(reply_word);
2383
2384     io_state = priv->io_state + index;
2385
2386         if (status == MPI_IOCSTATUS_TARGET_PRIORITY_IO) {
2387                 reason = rep->PriorityReason;
2388                 *io_state |= IO_STATE_HIGH_PRIORITY;
2389         } else {
2390                 reason = 0;
2391         }
2392
2393     TRACE_DBG("%s: target reply error", ioc->name);
2394     TRACE_DBG("%s: ReplyWord = %08x, IOCStatus = %04x",
2395            ioc->name, reply_word, status);
2396
2397         if (*io_state & IO_STATE_REQUEST_ABORTED) {
2398                 TRACE_DBG("%s: index %d: io_state = %x",
2399                                 ioc->name, index, *io_state);
2400                 TRACE_DBG("%s:   request was aborted", ioc->name);
2401                 *io_state &= ~IO_STATE_REQUEST_ABORTED;
2402                 if (*io_state & IO_STATE_REISSUE_REQUEST) {
2403                         *io_state &= ~IO_STATE_REISSUE_REQUEST;
2404                         TRACE_DBG("%s:   being reissued", ioc->name);
2405                         if (*io_state & IO_STATE_ADJUST_OFFSET) {
2406                                 *io_state &= ~IO_STATE_ADJUST_OFFSET;
2407                                 stmapp_srr_adjust_offset(priv, index);
2408                         }
2409                         if (*io_state & IO_STATE_CONVERT_TA_TO_TSS) {
2410                                 *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2411                                 stmapp_srr_convert_ta_to_tss(priv, index);
2412                                 goto out;
2413                         }
2414                         if (*io_state & IO_STATE_REDO_COMMAND) {
2415                                 *io_state &= ~IO_STATE_REDO_COMMAND;
2416                                 *io_state &= ~IO_STATE_DATA_SENT;
2417                                 *io_state &= ~IO_STATE_STATUS_SENT;
2418                                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
2419                                 stmapp_tgt_command(priv, reply_word);
2420                                 goto out;
2421                         }
2422                         mpt_put_msg_frame(stm_context, _IOC_ID, priv->current_mf[index]);
2423                         goto out;
2424                 }
2425         }
2426
2427     stmapp_target_error(priv, reply_word, index, status, reason);
2428 out:
2429         TRACE_EXIT();
2430 }
2431
2432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2433 static void
2434 stm_target_cleanup(MPT_STM_PRIV *priv,
2435                    int index)
2436 {
2437     MPT_ADAPTER         *ioc = priv->ioc;
2438     volatile int        *io_state;
2439
2440         TRACE_ENTRY();
2441         io_state = priv->io_state + index;
2442         if (*io_state & (IO_STATE_DATA_SENT | IO_STATE_STATUS_SENT)) {
2443                 *io_state &= ~IO_STATE_DATA_SENT;
2444                 *io_state &= ~IO_STATE_STATUS_SENT;
2445                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->current_mf[index]);
2446         }
2447         if (*io_state & IO_STATE_STATUS_DEFERRED) {
2448                 *io_state &= ~IO_STATE_STATUS_DEFERRED;
2449                 mpt_free_msg_frame(_HANDLE_IOC_ID, priv->status_deferred_mf[index]);
2450         }
2451         *io_state &= ~IO_STATE_REISSUE_REQUEST;
2452         *io_state &= ~IO_STATE_ADJUST_OFFSET;
2453         *io_state &= ~IO_STATE_CONVERT_TA_TO_TSS;
2454         *io_state &= ~IO_STATE_REDO_COMMAND;
2455         *io_state &= ~IO_STATE_REQUEST_ABORTED;
2456         *io_state &= ~IO_STATE_INCOMPLETE;
2457         //  *io_state &= ~IO_STATE_AUTO_REPOST;
2458         *io_state &= ~IO_STATE_ABORTED;
2459         *io_state &= ~IO_STATE_POSTED;
2460         if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == IO_STATE_AUTO_REPOST) {
2461                 *io_state = IO_STATE_POSTED;
2462         } else if ((*io_state & ~IO_STATE_HIGH_PRIORITY) == 0) {
2463                 stm_cmd_buf_post(priv, index);
2464         }
2465         TRACE_EXIT();
2466 }
2467
2468 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2469 static int
2470 stm_event_process(MPT_ADAPTER *ioc,
2471                   EventNotificationReply_t *rep)
2472 {
2473     MPT_STM_PRIV                *priv = mpt_stm_priv[ioc->id];
2474     EventDataScsi_t             *scsi_data;
2475     EventDataLinkStatus_t       *link_status_data;
2476     EventDataLoopState_t        *loop_state_data;
2477     EventDataLogout_t           *logout_data;
2478     EventDataSasPhyLinkStatus_t *sas_phy_link_status_data;
2479     int                         id;
2480     int                         i;
2481     int                         ioc_status;
2482     int                         event;
2483     int                         rate;
2484
2485         TRACE_ENTRY();
2486     if (priv == NULL) {
2487                 return (1);
2488         }
2489
2490     ioc_status = le16_to_cpu(rep->IOCStatus);
2491     event = le32_to_cpu(rep->Event);
2492
2493         if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
2494                 printk("%s Event = %x, IOCLogInfo = %08x\n",
2495                                 ioc->name, event, le32_to_cpu(rep->IOCLogInfo));
2496         }
2497
2498     switch (event) {
2499         case MPI_EVENT_NONE:
2500         case MPI_EVENT_LOG_DATA:
2501         case MPI_EVENT_STATE_CHANGE:
2502         case MPI_EVENT_UNIT_ATTENTION:
2503         case MPI_EVENT_EVENT_CHANGE:
2504         case MPI_EVENT_INTEGRATED_RAID:
2505         case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
2506         case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
2507         case MPI_EVENT_QUEUE_FULL:
2508         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2509         case MPI_EVENT_SAS_SES:
2510         case MPI_EVENT_PERSISTENT_TABLE_FULL:
2511         case MPI_EVENT_SAS_DISCOVERY_ERROR:
2512             break;
2513
2514         case MPI_EVENT_RESCAN:
2515             printk("%s Rescan\n", ioc->name);
2516             break;
2517
2518         case MPI_EVENT_IOC_BUS_RESET:
2519             scsi_data = (EventDataScsi_t *)rep->Data;
2520             printk("%s IOC Bus Reset on port %d\n",
2521                    ioc->name, scsi_data->BusPort);
2522             break;
2523
2524         case MPI_EVENT_EXT_BUS_RESET:
2525             scsi_data = (EventDataScsi_t *)rep->Data;
2526             printk("%s Ext Bus Reset on port %d\n",
2527                    ioc->name, scsi_data->BusPort);
2528             /*
2529              * clear any pending sense flags on bus reset
2530              */
2531             if (IsScsi(priv)) {
2532                     for (i = 0; i < NUM_SCSI_DEVICES; i++) {
2533                             atomic_set(&priv->pending_sense[i],
2534                                             MPT_STATUS_SENSE_IDLE);
2535                     }
2536             }
2537             break;
2538
2539         case MPI_EVENT_LINK_STATUS_CHANGE:
2540             link_status_data = (EventDataLinkStatus_t *)rep->Data;
2541             printk("%s Link is now %s\n",
2542                    ioc->name, link_status_data->State ? "Up" : "Down");
2543             break;
2544
2545         case MPI_EVENT_LOGOUT:
2546             logout_data = (EventDataLogout_t *)rep->Data;
2547             id = le32_to_cpu(logout_data->NPortID);
2548             break;
2549
2550         case MPI_EVENT_LOOP_STATE_CHANGE:
2551             loop_state_data = (EventDataLoopState_t *)rep->Data;
2552             if (loop_state_data->Type == MPI_EVENT_LOOP_STATE_CHANGE_LIP) {
2553                 printk("%s LIP Reset\n", ioc->name);
2554                 break;
2555             } /* fall-through */
2556
2557         case MPI_EVENT_SAS_PHY_LINK_STATUS:
2558             sas_phy_link_status_data = (EventDataSasPhyLinkStatus_t *)rep->Data;
2559             rate = (sas_phy_link_status_data->LinkRates &
2560                     MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
2561                      MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
2562             printk("%s Phy %d Handle %x is now %s\n",
2563                    ioc->name, sas_phy_link_status_data->PhyNum,
2564                    le16_to_cpu(sas_phy_link_status_data->DevHandle),
2565                    rate == MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN ? "offline" :
2566                    rate == MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED ? "disabled" :
2567                    rate == MPI_EVENT_SAS_PLS_LR_RATE_1_5 ? "online at 1.5 Gb" :
2568                    rate == MPI_EVENT_SAS_PLS_LR_RATE_3_0 ? "online at 3.0 Gb" :
2569                    "unknown");
2570             break;
2571
2572         default:
2573             printk("%s event = %d, ack = %d, length = %d\n",
2574                    ioc->name, le32_to_cpu(rep->Event),
2575                    rep->AckRequired, le16_to_cpu(rep->EventDataLength));
2576             for (i = 0; i < le16_to_cpu(rep->EventDataLength); i++) {
2577                 printk("%s data[%d] = %08x\n",
2578                        ioc->name, i, le32_to_cpu(rep->Data[i]));
2579             }
2580             break;
2581     }
2582
2583     if (event == MPI_EVENT_EXT_BUS_RESET) {
2584 #if 0
2585         if (IsScsi(priv)) {
2586             memset(priv->luns->drop, 0, sizeof(priv->luns->drop));
2587         }
2588 #endif
2589     }
2590         TRACE_EXIT();
2591
2592     return (1);
2593 }
2594
2595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2596 static int
2597 stm_reset_process(MPT_ADAPTER *ioc, int phase)
2598 {
2599     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2600     int                 i;
2601
2602         TRACE_ENTRY();
2603         if (priv == NULL)
2604                 return (1);
2605
2606         if (phase == MPT_IOC_PRE_RESET) {
2607                 printk(KERN_ERR MYNAM ":%s IOC will be reset\n",
2608                                 ioc->name);
2609                 priv->in_reset = 1;
2610                 priv->config_pending = 0;
2611                 for (i = 0; i < priv->num_cmd_buffers; i++)
2612                         priv->io_state[i] = 0;
2613         }
2614
2615         if (phase == MPT_IOC_POST_RESET) {
2616                 printk(KERN_ERR MYNAM ":%s IOC has been reset, restarting now\n",
2617                                 ioc->name);
2618                 mpt_stm_adapter_online(priv);
2619         }
2620
2621         TRACE_EXIT();
2622
2623     return (1);
2624 }
2625
2626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2627 static void
2628 stm_link_service_reply(MPT_ADAPTER *ioc, LinkServiceBufferPostReply_t *rep)
2629 {
2630     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2631     FC_ELS              *fc_els_buf;
2632     int                 index;
2633     int                 rctl;
2634     int                 type;
2635     int                 sid;
2636     int                 did;
2637     int                 command;
2638     int                 i;
2639     u32                 wwnnh;
2640     u32                 wwnnl;
2641     u32                 wwpnh;
2642     u32                 wwpnl;
2643     int                 ox_id;
2644     int                 rx_id;
2645     u32                 offset;
2646
2647         TRACE_ENTRY();
2648     index = le32_to_cpu(rep->TransactionContext);
2649     fc_els_buf = &priv->hw->fc_link_serv_buf[index];
2650
2651     rctl =
2652         (le32_to_cpu(rep->Rctl_Did) & MPI_FC_RCTL_MASK) >> MPI_FC_RCTL_SHIFT;
2653     type =
2654         (le32_to_cpu(rep->Type_Fctl) & MPI_FC_TYPE_MASK) >> MPI_FC_TYPE_SHIFT;
2655     sid =
2656         (le32_to_cpu(rep->Csctl_Sid) & MPI_FC_SID_MASK) >> MPI_FC_SID_SHIFT;
2657     did =
2658         (le32_to_cpu(rep->Rctl_Did) & MPI_FC_DID_MASK) >> MPI_FC_DID_SHIFT;
2659
2660     wwnnh = le32_to_cpu(rep->Wwn.NodeNameHigh);
2661     wwnnl = le32_to_cpu(rep->Wwn.NodeNameLow);
2662     wwpnh = le32_to_cpu(rep->Wwn.PortNameHigh);
2663     wwpnl = le32_to_cpu(rep->Wwn.PortNameLow);
2664
2665     ox_id = le16_to_cpu(rep->Oxid);
2666     rx_id = le16_to_cpu(rep->Rxid);
2667
2668     /*
2669      *  if this is a received PRLI/PRLO, respond by sending our own PRLI/PRLO
2670      */
2671     if (rctl == ELS && type == 0x01) {
2672         command = (be32_to_cpu(fc_els_buf->fc_els[0]) >> 24) & 0xff;
2673         switch (command) {
2674             case PRLI:
2675                 TRACE_DBG("%s: PRLI to %06x from %06x (wwn %08x%08x)",
2676                                 ioc->name, did, sid, wwpnh, wwpnl);
2677                 i = be32_to_cpu(fc_els_buf->fc_els[4]);
2678                 fc_els_buf->fc_els[0] = cpu_to_be32(0x02100014);
2679                 fc_els_buf->fc_els[1] = cpu_to_be32(0x08002100);
2680                 fc_els_buf->fc_els[2] = cpu_to_be32(0x00000000);
2681                 fc_els_buf->fc_els[3] = cpu_to_be32(0x00000000);
2682                 fc_els_buf->fc_els[4] = cpu_to_be32(0x00000012);
2683                 if (priv->fcp2_capable)
2684                     fc_els_buf->fc_els[4] |= cpu_to_be32(0x100);
2685                 priv->els_state[index] = PRLI;
2686                 stm_send_els(priv, rep, index, 20);
2687                 return;
2688
2689             case PRLO:
2690                 TRACE_DBG("%s: PRLO to %06x from %06x (wwn %08x%08x)",
2691                         ioc->name, did, sid, wwpnh, wwpnl);
2692                 fc_els_buf->fc_els[0] = cpu_to_be32(0x02100014);
2693                 fc_els_buf->fc_els[1] = cpu_to_be32(0x08000100);
2694                 fc_els_buf->fc_els[2] = cpu_to_be32(0x00000000);
2695                 fc_els_buf->fc_els[3] = cpu_to_be32(0x00000000);
2696                 fc_els_buf->fc_els[4] = cpu_to_be32(0x00000000);
2697                 priv->els_state[index] = PRLO;
2698                 stm_send_els(priv, rep, index, 20);
2699                 return;
2700
2701             case RSCN:
2702                 TRACE_DBG("%s: RSCN", ioc->name);
2703                 stm_link_serv_buf_post(priv, index);
2704                 return;
2705
2706             default:
2707                 TRACE_DBG("%s: ELS %02x to %06x from %06x (wwn %08x%08x)",
2708                         ioc->name, command, did, sid, wwpnh, wwpnl);
2709                 stm_link_serv_buf_post(priv, index);
2710                 return;
2711         }
2712     }
2713
2714     /*
2715      *  if this is a received ABTS, respond by aborting the I/O and then
2716      *  accepting it
2717      */
2718     if (rctl == ABTS && type == 0x00) {
2719         TRACE_DBG("%s: ABTS to %06x from %06x (wwn %08x%08x)",
2720                 ioc->name, did, sid, wwpnh, wwpnl);
2721         fc_els_buf->fc_els[0] = cpu_to_be32(0x00000000);
2722         fc_els_buf->fc_els[1] = cpu_to_be32((ox_id << 16) | (rx_id << 0));
2723         fc_els_buf->fc_els[2] = cpu_to_be32(0x0000ffff);
2724         rep->Rctl_Did += cpu_to_le32((BA_ACC - ABTS) << MPI_FC_RCTL_SHIFT);
2725         priv->els_state[index] = ABTS;
2726         stmapp_abts_process(priv, rx_id, rep, index);
2727         stm_send_els(priv, rep, index, 12);
2728         return;
2729     }
2730
2731     /*
2732      *  if this is a received SRR, respond by aborting any current TargetAssist
2733      *  or TargetStatusSend commands, accepting the SRR, and retransmitting the
2734      *  requested data or status
2735      */
2736     if (rctl == FC4LS && type == 0x08) {
2737         priv->els_state[index] = FC4LS;
2738         command = (be32_to_cpu(fc_els_buf->fc_els[0]) >> 24) & 0xff;
2739         switch (command) {
2740             case SRR:
2741                 TRACE_DBG("%s: SRR to %06x from %06x (wwn %08x%08x)",
2742                         ioc->name, did, sid, wwpnh, wwpnl);
2743                 rx_id = be32_to_cpu(fc_els_buf->fc_els[1]) & 0xffff;
2744                 /*
2745                  *  if the rx_id is out of range, reject this SRR with
2746                  *  "invalid OX_ID/RX_ID combination"
2747                  */
2748                 if (rx_id >= priv->num_cmd_buffers) {
2749                     fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2750                     fc_els_buf->fc_els[1] = cpu_to_be32(0x00090300);
2751                     stm_send_els(priv, rep, index, 8);
2752                     return;
2753                 }
2754                 i = (be32_to_cpu(fc_els_buf->fc_els[3]) >> 24) & 0xff;
2755                 /*
2756                  *  if the IU to retransmit is not a recognized IU, reject
2757                  *  this SRR with "logical error"
2758                  */
2759                 if (i != 1 && i != 5 && i != 7) {
2760                     fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2761                     fc_els_buf->fc_els[1] = cpu_to_be32(0x00030000);
2762                     stm_send_els(priv, rep, index, 8);
2763                     return;
2764                 }
2765                 offset = be32_to_cpu(fc_els_buf->fc_els[2]);
2766                 /*
2767                  *  go process this SRR further
2768                  *
2769                  *  make the call to stm_send_els when any request in progress
2770                  *  has been aborted
2771                  *
2772                  *  note that the address of the LinkServiceBufferPostReply
2773                  *  that's passed as a parameter to stmapp_abts_process CANNOT
2774                  *  BE REMEMBERED; its contents must be copied if the call to
2775                  *  stm_send_els will not be made synchronously
2776                  */
2777                 stmapp_srr_process(priv, rx_id, i, offset, rep, index);
2778                 return;
2779
2780             default:
2781                 TRACE_DBG("%s: FC4LS %02x to %06x from %06x (wwn %08x%08x)",
2782                         ioc->name, command, did, sid, wwpnh, wwpnl);
2783                 /*
2784                  *  the only FC4LS we recognize is SRR; all others get
2785                  *  rejected with "command not supported"
2786                  */
2787                 fc_els_buf->fc_els[0] = cpu_to_be32(0x01000000);
2788                 fc_els_buf->fc_els[1] = cpu_to_be32(0x000b0000);
2789                 stm_send_els(priv, rep, index, 8);
2790                 return;
2791         }
2792     }
2793
2794 #ifdef TRACING
2795         if(trace_mpi)
2796         {
2797                 u32 *p = (u32 *)rep;
2798                 int i;
2799
2800                 for (i = 0; i < 17; i++) {
2801                         TRACE(TRACE_MPI, "%s: fc_els[%02x] = %08x",
2802                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2803                 }
2804         }
2805         if(trace_mpi)
2806         {
2807                 u32 *p = (u32 *)fc_els_buf;
2808                 int i;
2809
2810                 for (i = 0; i < (int)le32_to_cpu(rep->TransferLength) / 4; i++) {
2811                         TRACE(TRACE_MPI, "%s: fc_els_buf[%02x] = %08x",
2812                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2813                 }
2814         }
2815 #endif
2816
2817     stm_link_serv_buf_post(priv, index);
2818         TRACE_EXIT();
2819 }
2820
2821 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2822 static void
2823 stm_link_service_rsp_reply(MPT_ADAPTER *ioc,
2824                            LinkServiceRspRequest_t *req,
2825                            LinkServiceRspReply_t *rep)
2826 {
2827     MPT_STM_PRIV        *priv = mpt_stm_priv[ioc->id];
2828     MPT_STM_SIMPLE      *sge_simple;
2829     int                 *p_index;
2830     int                 index;
2831     int                 sid;
2832     int                 did;
2833     int                 els;
2834     int                 init_index;
2835
2836         TRACE_ENTRY();
2837     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
2838     p_index = (int *)(sge_simple + 1);
2839     index = *p_index;
2840     els = priv->els_state[index];
2841
2842     sid = (le32_to_cpu(req->Csctl_Sid) & MPI_FC_SID_MASK) >> MPI_FC_SID_SHIFT;
2843     did = (le32_to_cpu(req->Rctl_Did) & MPI_FC_DID_MASK) >> MPI_FC_DID_SHIFT;
2844     init_index = le32_to_cpu(rep->InitiatorIndex);
2845     /*
2846      *  after our link service reponse has been sent, repost the link service
2847      *  buffer
2848      */
2849     priv->els_state[index] = 0;
2850     stm_link_serv_buf_post(priv, index);
2851         TRACE_EXIT();
2852 }
2853
2854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2855 static void
2856 stm_cmd_buf_post(MPT_STM_PRIV *priv, int index)
2857 {
2858     MPT_ADAPTER *ioc = priv->ioc;
2859     TargetCmdBufferPostRequest_t *req;
2860     dma_addr_t  dma_addr;
2861
2862         TRACE_ENTRY();
2863         if (priv->exiting) {
2864                 priv->io_state[index] |= IO_STATE_POSTED;
2865                 return;
2866         }
2867
2868         if (IsSas(priv)) {
2869                 stm_cmd_buf_post_list(priv, index);
2870                 return;
2871         }
2872
2873     /*
2874      *  get a free message frame, and post a command buffer
2875      */
2876     req = (TargetCmdBufferPostRequest_t *)mpt_msg_frame_alloc(ioc,-1);
2877     memset(req, 0, sizeof(*req));
2878
2879 #ifdef CMD_BUFFER_POST_FLAGS_HIGH_PRIORITY
2880         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
2881                 req->BufferPostFlags = CMD_BUFFER_POST_FLAGS_HIGH_PRIORITY;
2882         }
2883 #else
2884         priv->io_state[index] &= ~IO_STATE_HIGH_PRIORITY;
2885 #endif
2886
2887     req->BufferCount = 1;
2888     req->Function = MPI_FUNCTION_TARGET_CMD_BUFFER_POST;
2889     req->BufferLength = sizeof(priv->hw->cmd_buf[index].cmd);
2890     req->Buffer[0].IoIndex = cpu_to_le16(index);
2891     dma_addr = priv->hw_dma +
2892         ((u8 *)priv->hw->cmd_buf[index].cmd - (u8 *)priv->hw);
2893     req->Buffer[0].u.PhysicalAddress64.Low = cpu_to_le32(dma_addr);
2894 #if MPT_STM_64_BIT_DMA
2895     req->Buffer[0].u.PhysicalAddress64.High = cpu_to_le32((u64)dma_addr>>32);
2896     req->BufferPostFlags = CMD_BUFFER_POST_FLAGS_64_BIT_ADDR;
2897 #endif
2898
2899     priv->io_state[index] |= IO_STATE_POSTED;
2900
2901 #ifdef TRACING
2902         if(trace_mpi) {
2903                 u32 *p = (u32 *)req;
2904                 int i;
2905
2906                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post %d", ioc->name, index);
2907                 for (i = 0; i < sizeof(*req) / 4; i++) {
2908                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
2909                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2910                 }
2911         }
2912 #endif
2913
2914         if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
2915                 priv->io_state[index] &= ~IO_STATE_HIGH_PRIORITY;
2916                 mpt_send_handshake_request(stm_context, _IOC_ID,
2917                                 sizeof(*req), (u32 *)req _HS_SLEEP);
2918         } else {
2919                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
2920         }
2921
2922         TRACE_EXIT();
2923 }
2924
2925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2926 static void
2927 stm_cmd_buf_post_base(MPT_STM_PRIV *priv,
2928                       int post_all)
2929 {
2930     MPT_ADAPTER                         *ioc = priv->ioc;
2931     TargetCmdBufferPostBaseRequest_t    *req;
2932     int                                 i;
2933     dma_addr_t                          dma_addr;
2934
2935         TRACE_ENTRY();
2936     req = (TargetCmdBufferPostBaseRequest_t *)mpt_msg_frame_alloc(ioc,-1);
2937     memset(req, 0, sizeof(*req));
2938
2939     if (post_all) {
2940         req->BufferPostFlags = CMD_BUFFER_POST_BASE_FLAGS_AUTO_POST_ALL;
2941     }
2942     req->Function = MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST;
2943     req->TotalCmdBuffers = cpu_to_le16(priv->num_cmd_buffers);
2944     req->CmdBufferLength = cpu_to_le16(sizeof(priv->hw->cmd_buf[0].cmd));
2945     req->NextCmdBufferOffset = cpu_to_le16(sizeof(priv->hw->cmd_buf[0]));
2946     dma_addr = priv->hw_dma +
2947         ((u8 *)priv->hw->cmd_buf[0].cmd - (u8 *)priv->hw);
2948     req->BaseAddressLow = cpu_to_le32(dma_addr);
2949 #if MPT_STM_64_BIT_DMA
2950     req->BaseAddressHigh = cpu_to_le32((u64)dma_addr>>32);
2951 #endif
2952
2953     if (post_all) {
2954         for (i = 0; i < priv->num_cmd_buffers; i++) {
2955             priv->io_state[i] |= IO_STATE_POSTED;
2956         }
2957     }
2958
2959 #ifdef TRACING
2960         if(trace_mpi)
2961         {
2962                 u32 *p = (u32 *)req;
2963                 int i;
2964
2965                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post_base", ioc->name);
2966                 for (i = 0; i < sizeof(*req) / 4; i++) {
2967                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
2968                                         ioc->name, i * 4, le32_to_cpu(p[i]));
2969                 }
2970         }
2971 #endif
2972
2973     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
2974
2975         TRACE_EXIT();
2976 }
2977
2978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2979 static void
2980 stm_cmd_buf_post_list(MPT_STM_PRIV *priv,
2981                       int index)
2982 {
2983     MPT_ADAPTER                         *ioc = priv->ioc;
2984     TargetCmdBufferPostListRequest_t    *req;
2985
2986         TRACE_ENTRY();
2987     req = (TargetCmdBufferPostListRequest_t *)mpt_msg_frame_alloc(ioc,-1);
2988     memset(req, 0, sizeof(*req));
2989
2990     req->Function = MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST;
2991     req->CmdBufferCount = cpu_to_le16(1);
2992     req->IoIndex[0] = cpu_to_le16(index);
2993
2994     priv->io_state[index] |= IO_STATE_POSTED;
2995
2996 #ifdef TRACING
2997         if(trace_mpi)
2998         {
2999                 u32 *p = (u32 *)req;
3000                 int i;
3001
3002                 TRACE(TRACE_MPI, "%s: stm_cmd_buf_post_list %d", ioc->name, index);
3003                 for (i = 0; i < sizeof(*req) / 4; i++) {
3004                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3005                                         ioc->name, i * 4, le32_to_cpu(p[i]));
3006                 }
3007         }
3008 #endif
3009
3010         mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3011         TRACE_EXIT();
3012 }
3013
3014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3015 static void
3016 stm_link_serv_buf_post(MPT_STM_PRIV *priv, int index)
3017 {
3018     MPT_ADAPTER                         *ioc = priv->ioc;
3019     LinkServiceBufferPostRequest_t      *req;
3020     SGETransaction32_t                  *sge_trans;
3021     MPT_STM_SIMPLE                      *sge_simple;
3022     dma_addr_t                          dma_addr;
3023
3024         TRACE_ENTRY();
3025     req = (LinkServiceBufferPostRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3026     memset(req, 0, sizeof(*req));
3027
3028     req->BufferCount = 1;
3029     req->Function = MPI_FUNCTION_FC_LINK_SRVC_BUF_POST;
3030     sge_trans = (SGETransaction32_t *)&req->SGL;
3031     sge_trans->ContextSize = 4;
3032     sge_trans->DetailsLength = 0;
3033     sge_trans->Flags = 0;
3034     sge_trans->TransactionContext[0] = cpu_to_le32(index);
3035     sge_simple = (MPT_STM_SIMPLE *)&sge_trans->TransactionDetails[0];
3036     sge_simple->FlagsLength = cpu_to_le32(sizeof(FC_ELS) |
3037         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3038                           MPI_SGE_FLAGS_LAST_ELEMENT |
3039                           MPI_SGE_FLAGS_END_OF_BUFFER |
3040                           MPI_SGE_FLAGS_END_OF_LIST |
3041                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3042                           MPI_SGE_FLAGS_HOST_TO_IOC));
3043     dma_addr = priv->hw_dma +
3044         ((u8 *)priv->hw->fc_link_serv_buf[index].fc_els - (u8 *)priv->hw);
3045     stm_set_dma_addr(sge_simple->Address, dma_addr);
3046
3047 #ifdef TRACING
3048         if(trace_mpi)
3049         {
3050                 u32 *p = (u32 *)req;
3051                 int i;
3052
3053                 TRACE(TRACE_MPI, "%s: stm_link_serv_buf_post %d", ioc->name, index);
3054                 for (i = 0; i < sizeof(*req) / 4; i++) {
3055                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3056                                         ioc->name, i * 4, le32_to_cpu(p[i]));
3057                 }
3058         }
3059 #endif
3060     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3061         TRACE_EXIT();
3062 }
3063
3064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3065 static int
3066 stm_send_target_status(MPT_STM_PRIV *priv,
3067                        u32 reply_word, int index, int flags, int lun, int tag)
3068 {
3069     MPT_ADAPTER                 *ioc = priv->ioc;
3070     TargetStatusSendRequest_t   *req;
3071     MPT_STM_SIMPLE              *sge_simple;
3072     CMD                         *cmd;
3073     int                         length;
3074     int                         status;
3075     int                         init_index;
3076     dma_addr_t                  dma_addr;
3077
3078     TRACE_ENTRY();
3079     req = (TargetStatusSendRequest_t *)mpt_msg_frame_alloc(ioc,index);
3080     memset(req, 0, sizeof(*req));
3081
3082     if (priv->exiting) {
3083         flags &= ~TARGET_ASSIST_FLAGS_REPOST_CMD_BUFFER;
3084         priv->io_state[index] &= ~IO_STATE_AUTO_REPOST;
3085     }
3086
3087     if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
3088         flags |= TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY;
3089         flags |= TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
3090         priv->io_state[index] |= IO_STATE_AUTO_REPOST;
3091     }
3092
3093     if (priv->fcp2_capable/* && priv->initiators != NULL*/) {
3094         init_index = GET_INITIATOR_INDEX(reply_word);
3095         /*init = priv->initiators[init_index];
3096         if (init != NULL && init->confirm_capable) {
3097             flags |= TARGET_STATUS_SEND_FLAGS_CONFIRMED;
3098         }*/
3099     }
3100
3101     cmd = priv->hw->cmd_buf + index;
3102
3103     if (flags & TARGET_STATUS_SEND_FLAGS_AUTO_GOOD_STATUS) {
3104         length = 0;
3105         req->StatusCode = 0;
3106     } else {
3107         length = 0;
3108         if (IsScsi(priv)) {
3109             SCSI_RSP    *rsp = (SCSI_RSP *)cmd->rsp;
3110             size_t sense_size;
3111
3112             length += sizeof(*rsp);
3113             length -= sizeof(rsp->SenseData);
3114             status = rsp->Status;
3115             if (rsp->Valid & SCSI_SENSE_LEN_VALID) {
3116                 length += be32_to_cpu(rsp->SenseDataListLength);
3117                 init_index = GET_INITIATOR_INDEX(reply_word);
3118                 /*
3119                  *  try to avoid a SCSI firmware bug by not using Auto Repost
3120                  *  here, unless required (High Priority requires it)
3121                  */
3122                 if (!(priv->io_state[index] & IO_STATE_HIGH_PRIORITY)) {
3123                     flags &= ~TARGET_STATUS_SEND_FLAGS_REPOST_CMD_BUFFER;
3124                     priv->io_state[index] &= ~IO_STATE_AUTO_REPOST;
3125                 }
3126                 /*
3127                  * cache sense buffer so we can send it on the next
3128                  * REQUEST SENSE command if the IOC can't send the
3129                  * status and sense simultaneously (generating
3130                  * MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT IOCStatus)
3131                  */
3132                 sense_size = min(sizeof(rsp->SenseData),
3133                                        (size_t)SCSI_SENSE_BUFFERSIZE);
3134                 TRACE_DBG("caching %d bytes pending sense", sense_size);
3135                 memcpy(priv->pending_sense_buffer[init_index],
3136                                 rsp->SenseData, sense_size);
3137                 TRACE_BUFFER("priv->pending_sense_buffer",
3138                                 priv->pending_sense_buffer[init_index],
3139                                 sense_size);
3140                 atomic_set(&priv->pending_sense[init_index],
3141                                 MPT_STATUS_SENSE_ATTEMPT);
3142             }
3143             if (rsp->Valid & SCSI_RSP_LEN_VALID) {
3144                 length += be32_to_cpu(rsp->PktFailuresListLength);
3145             }
3146         } else if (IsSas(priv)) {
3147             SSP_RSP     *rsp = (SSP_RSP *)cmd->rsp;
3148
3149             length += sizeof(*rsp);
3150             length -= sizeof(rsp->ResponseSenseData);
3151             status = rsp->Status;
3152             if (rsp->DataPres & SSP_SENSE_LEN_VALID) {
3153                 length += be32_to_cpu(rsp->SenseDataLength);
3154             }
3155             if (rsp->DataPres & SSP_RSP_LEN_VALID) {
3156                 length += be32_to_cpu(rsp->ResponseDataLength);
3157             }
3158         } else {
3159             FCP_RSP     *rsp = (FCP_RSP *)cmd->rsp;
3160
3161             length += sizeof(*rsp);
3162             length -= sizeof(rsp->FcpSenseData) + sizeof(rsp->FcpResponseData);
3163             status = rsp->FcpStatus;
3164             if (flags & TARGET_STATUS_SEND_FLAGS_CONFIRMED) {
3165                 rsp->FcpFlags |= FCP_REQUEST_CONFIRM;
3166             }
3167             if (rsp->FcpFlags & FCP_SENSE_LEN_VALID) {
3168                 length += be32_to_cpu(rsp->FcpSenseLength);
3169             }
3170             if (rsp->FcpFlags & FCP_RSP_LEN_VALID) {
3171                 length += be32_to_cpu(rsp->FcpResponseLength);
3172                 /* FCP_RSP_LEN_VALID will only be set for Task Mgmt responses */
3173                 /* and Task Mgmt responses can't be confirmed */
3174                 rsp->FcpFlags &= ~FCP_REQUEST_CONFIRM;
3175                 flags &= ~TARGET_STATUS_SEND_FLAGS_CONFIRMED;
3176             }
3177         }
3178         req->StatusCode = (u8)status;
3179     }
3180
3181     req->StatusFlags = (u8)flags;
3182     req->Function = MPI_FUNCTION_TARGET_STATUS_SEND;
3183     req->QueueTag = (u16)tag;
3184     req->ReplyWord = cpu_to_le32(reply_word);
3185     req->LUN[0] = (u8)(lun >> 8);
3186     req->LUN[1] = (u8)lun;
3187     if (length != 0) {
3188         sge_simple = (MPT_STM_SIMPLE *)&req->StatusDataSGE;
3189         sge_simple->FlagsLength = cpu_to_le32(length |
3190             MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3191                               MPI_SGE_FLAGS_LAST_ELEMENT |
3192                               MPI_SGE_FLAGS_END_OF_BUFFER |
3193                               MPI_SGE_FLAGS_END_OF_LIST |
3194                               MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3195                               MPI_SGE_FLAGS_HOST_TO_IOC));
3196         dma_addr = priv->hw_dma +
3197             ((u8 *)priv->hw->cmd_buf[index].rsp - (u8 *)priv->hw);
3198         stm_set_dma_addr(sge_simple->Address, dma_addr);
3199     }
3200
3201     /*
3202      *  there's a limitation here -- if target data is outstanding, we must
3203      *  wait for it to finish before we send the target status
3204      */
3205     if (priv->io_state[index] & IO_STATE_DATA_SENT) {
3206             priv->status_deferred_mf[index] = (MPT_FRAME_HDR *)req;
3207             priv->io_state[index] |= IO_STATE_STATUS_DEFERRED;
3208             TRACE_EXIT_RES(1);
3209             return (1);
3210     }
3211     priv->io_state[index] |= IO_STATE_STATUS_SENT;
3212
3213 #ifdef TRACING
3214     if(trace_mpi)
3215     {
3216             u32 *p = (u32 *)req;
3217             int i;
3218
3219             TRACE(TRACE_MPI, "%s: stm_send_target_status %d",
3220                             ioc->name, index);
3221             for (i = 0; i < sizeof(*req) / 4; i++) {
3222                     TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3223                                     ioc->name, i * 4, le32_to_cpu(p[i]));
3224             }
3225     }
3226 #endif
3227
3228     if (priv->io_state[index] & IO_STATE_HIGH_PRIORITY) {
3229             mpt_send_handshake_request(stm_context, _IOC_ID,
3230                             sizeof(*req), (u32 *)req _HS_SLEEP);
3231     } else {
3232             mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3233     }
3234     TRACE_EXIT_RES(1);
3235     return (1);
3236 }
3237
3238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3239 static void
3240 stm_send_els(MPT_STM_PRIV *priv,
3241              LinkServiceBufferPostReply_t *rep, int index, int length)
3242 {
3243     MPT_ADAPTER                 *ioc = priv->ioc;
3244     LinkServiceRspRequest_t     *req;
3245     MPT_STM_SIMPLE              *sge_simple;
3246     int                         *p_index;
3247     dma_addr_t                  dma_addr;
3248
3249         TRACE_ENTRY();
3250     req = (LinkServiceRspRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3251     memset(req, 0, sizeof(*req));
3252
3253     req->RspLength = (u8)length;
3254     req->Function = MPI_FUNCTION_FC_LINK_SRVC_RSP;
3255     memcpy((u8 *)req + 0x0c, (u8 *)rep + 0x1c, 24);
3256     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3257     sge_simple->FlagsLength = cpu_to_le32(length |
3258         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3259                           MPI_SGE_FLAGS_LAST_ELEMENT |
3260                           MPI_SGE_FLAGS_END_OF_BUFFER |
3261                           MPI_SGE_FLAGS_END_OF_LIST |
3262                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3263                           MPI_SGE_FLAGS_HOST_TO_IOC));
3264     dma_addr = priv->hw_dma +
3265         ((u8 *)priv->hw->fc_link_serv_buf[index].fc_els - (u8 *)priv->hw);
3266     stm_set_dma_addr(sge_simple->Address, dma_addr);
3267     p_index = (int *)(sge_simple + 1);
3268     *p_index = index;
3269
3270 #ifdef TRACING
3271         if(trace_mpi)
3272         {
3273                 u32 *p = (u32 *)req;
3274                 int i;
3275
3276                 TRACE(TRACE_MPI, "%s: stm_send_els %d", ioc->name, index);
3277                 for (i = 0; i < sizeof(*req) / 4; i++) {
3278                         TRACE(TRACE_MPI, "%s: req[%02x] = %08x",
3279                                         ioc->name, i * 4, le32_to_cpu(p[i]));
3280                 }
3281         }
3282 #endif
3283     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3284         TRACE_EXIT();
3285 }
3286
3287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3288 static int
3289 stm_port_enable(MPT_STM_PRIV *priv)
3290 {
3291     MPT_ADAPTER         *ioc = priv->ioc;
3292     PortEnable_t        *req;
3293         int ret;
3294
3295         TRACE_ENTRY();
3296     req = (PortEnable_t *)mpt_msg_frame_alloc(ioc,-1);
3297     memset(req, 0, sizeof(*req));
3298
3299     req->Function = MPI_FUNCTION_PORT_ENABLE;
3300
3301     priv->port_enable_pending = 1;
3302
3303     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3304
3305     ret = stm_wait_for(priv, &priv->port_enable_pending, 60, NO_SLEEP);
3306
3307         TRACE_EXIT_RES(ret);
3308
3309         return ret;
3310 }
3311
3312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3313 static int
3314 stm_target_mode_abort_command(MPT_STM_PRIV *priv,
3315                               u32 reply_word, int index)
3316 {
3317     MPT_ADAPTER         *ioc = priv->ioc;
3318     TargetModeAbort_t   *req;
3319
3320         TRACE_ENTRY();
3321     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,-1);
3322     memset(req, 0, sizeof(*req));
3323
3324     req->AbortType = TARGET_MODE_ABORT_TYPE_EXACT_IO;
3325     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3326     req->ReplyWord = cpu_to_le32(reply_word);
3327
3328     priv->io_state[index] |= IO_STATE_ABORTED;
3329
3330         if (IsScsi(priv)) {
3331                 mpt_send_handshake_request(stm_context, _IOC_ID,
3332                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3333         } else {
3334                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3335         }
3336         TRACE_EXIT();
3337
3338     return (0);
3339 }
3340
3341 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3342 static int
3343 stm_target_mode_abort_request(MPT_STM_PRIV *priv,
3344                               u32 reply_word,
3345                               u32 msg_context,
3346                               int index)
3347 {
3348     MPT_ADAPTER         *ioc = priv->ioc;
3349     TargetModeAbort_t   *req;
3350
3351         TRACE_ENTRY();
3352     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,-1);
3353     memset(req, 0, sizeof(*req));
3354
3355     req->AbortType = TARGET_MODE_ABORT_TYPE_EXACT_IO_REQUEST;
3356     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3357     req->ReplyWord = cpu_to_le32(reply_word);
3358     req->MsgContextToAbort = cpu_to_le32(msg_context);
3359
3360     priv->io_state[index] |= IO_STATE_REQUEST_ABORTED;
3361
3362         if (IsScsi(priv)) {
3363                 mpt_send_handshake_request(stm_context, _IOC_ID,
3364                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3365         } else {
3366                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3367         }
3368         TRACE_EXIT();
3369
3370     return (0);
3371 }
3372
3373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3374 static int
3375 stm_target_mode_abort_all(MPT_STM_PRIV *priv)
3376 {
3377     MPT_ADAPTER         *ioc = priv->ioc;
3378     TargetModeAbort_t   *req;
3379         int ret;
3380         TRACE_ENTRY();
3381
3382     req = (TargetModeAbort_t *)mpt_msg_frame_alloc(ioc,-1);
3383     memset(req, 0, sizeof(*req));
3384
3385     req->AbortType = TARGET_MODE_ABORT_TYPE_ALL_CMD_BUFFERS;
3386     req->Function = MPI_FUNCTION_TARGET_MODE_ABORT;
3387
3388     priv->target_mode_abort_pending = 1;
3389
3390         if (IsScsi(priv)) {
3391                 mpt_send_handshake_request(stm_context, _IOC_ID,
3392                                 sizeof(*req), (u32 *)req _HS_SLEEP);
3393         } else {
3394                 mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3395         }
3396
3397     ret = stm_wait_for(priv, &priv->target_mode_abort_pending, 60, NO_SLEEP);
3398         TRACE_EXIT_RES(ret);
3399
3400         return ret;
3401 }
3402
3403 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3404 static int
3405 stm_target_mode_abort(MPT_STM_PRIV *priv)
3406 {
3407 #ifdef DEBUG
3408     MPT_ADAPTER         *ioc = priv->ioc;
3409 #endif
3410     int                 i;
3411     int                 n;
3412
3413         TRACE_ENTRY();
3414         while (1) {
3415                 n = 0;
3416                 for (i = 0; i< priv->num_cmd_buffers; i++) {
3417                         if (priv->io_state[i] & IO_STATE_AUTO_REPOST) {
3418                                 n++;
3419                         }
3420                 }
3421
3422                 if (n == 0)
3423                         break;
3424
3425                 TRACE_DBG("%s: %d out of %d commands being auto-reposted, waiting...",
3426                                 ioc->name, n, priv->num_cmd_buffers);
3427                 stm_wait(priv, 10, CAN_SLEEP);
3428         }
3429
3430         while (1) {
3431                 stm_target_mode_abort_all(priv);
3432
3433                 n = 0;
3434                 for (i = 0; i< priv->num_cmd_buffers; i++) {
3435                         if (priv->io_state[i] & IO_STATE_POSTED) {
3436                                 n++;
3437                         }
3438                 }
3439
3440                 if (n == priv->num_cmd_buffers)
3441                         break;
3442
3443                 TRACE_DBG("%s: %d out of %d commands still active, waiting...",
3444                                 ioc->name, n, priv->num_cmd_buffers);
3445                 stm_wait(priv, 10, CAN_SLEEP);
3446         }
3447
3448         TRACE_EXIT();
3449     return (0);
3450 }
3451
3452 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3453 static int
3454 stm_link_serv_abort(MPT_STM_PRIV *priv)
3455 {
3456     MPT_ADAPTER         *ioc = priv->ioc;
3457     FcAbortRequest_t    *req;
3458         int ret;
3459
3460         TRACE_ENTRY();
3461
3462     req = (FcAbortRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3463     memset(req, 0, sizeof(*req));
3464
3465     req->AbortType = FC_ABORT_TYPE_ALL_FC_BUFFERS;
3466     req->Function = MPI_FUNCTION_FC_ABORT;
3467
3468     priv->link_serv_abort_pending = 1;
3469
3470     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3471
3472     ret = stm_wait_for(priv, &priv->link_serv_abort_pending, 60, NO_SLEEP);
3473
3474         TRACE_EXIT_RES(ret);
3475
3476         return ret;
3477 }
3478
3479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3480 static int
3481 stm_reset_link(MPT_STM_PRIV *priv)
3482 {
3483     MPT_ADAPTER                 *ioc = priv->ioc;
3484     FcPrimitiveSendRequest_t    *req;
3485         int ret;
3486
3487         TRACE_ENTRY();
3488     req = (FcPrimitiveSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3489     memset(req, 0, sizeof(*req));
3490
3491     req->SendFlags = MPI_FC_PRIM_SEND_FLAGS_RESET_LINK;
3492     req->Function = MPI_FUNCTION_FC_PRIMITIVE_SEND;
3493
3494     priv->fc_primitive_send_pending = 1;
3495
3496     mpt_put_msg_frame(stm_context, _IOC_ID, (MPT_FRAME_HDR *)req);
3497
3498     ret = stm_wait_for(priv, &priv->fc_primitive_send_pending, 60, NO_SLEEP);
3499         TRACE_EXIT_RES(ret);
3500
3501         return ret;
3502 }
3503 #if 0
3504 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3505 static int
3506 stm_login_port(MPT_STM_PRIV *priv, int port_id, int sleep)
3507 {
3508     MPT_ADAPTER                 *ioc = priv->ioc;
3509     ExLinkServiceSendRequest_t  *req;
3510     MPT_STM_SIMPLE              *sge_simple;
3511     u32                         *buf;
3512     int                         len, ret;
3513     dma_addr_t                  dma_addr;
3514
3515         TRACE_ENTRY();
3516     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3517     memset(req, 0, sizeof(*req));
3518
3519     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3520     req->MsgFlags_Did = cpu_to_le32(port_id);
3521     req->ElsCommandCode = cpu_to_le32(PLOGI);
3522
3523     len = 29 * 4;
3524     buf = priv->hw->exlink_buf;
3525     memset(buf, 0, len);
3526
3527     buf[0] = cpu_to_be32(PLOGI << 24);
3528     /*
3529      *  the firmware builds the rest of the PLOGI payload
3530      */
3531
3532     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3533     sge_simple->FlagsLength = cpu_to_le32(len |
3534         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3535                           MPI_SGE_FLAGS_END_OF_BUFFER |
3536                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3537                           MPI_SGE_FLAGS_HOST_TO_IOC));
3538     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3539     stm_set_dma_addr(sge_simple->Address, dma_addr);
3540     sge_simple++;
3541     sge_simple->FlagsLength = cpu_to_le32(len |
3542         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3543                           MPI_SGE_FLAGS_LAST_ELEMENT |
3544                           MPI_SGE_FLAGS_END_OF_BUFFER |
3545                           MPI_SGE_FLAGS_END_OF_LIST |
3546                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3547                           MPI_SGE_FLAGS_IOC_TO_HOST));
3548     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3549     stm_set_dma_addr(sge_simple->Address, dma_addr);
3550
3551     priv->ex_link_service_send_pending = 1;
3552
3553     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3554
3555     if (stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep) < 0)
3556         return (-1);
3557
3558     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3559     memset(req, 0, sizeof(*req));
3560
3561     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3562     req->MsgFlags_Did = cpu_to_le32(port_id);
3563     req->ElsCommandCode = cpu_to_le32(PRLI);
3564
3565     len = 5 * 4;
3566     buf = priv->hw->exlink_buf;
3567     memset(buf, 0, len);
3568
3569     buf[0] = cpu_to_be32(0x00100014 | (PRLI << 24));
3570     buf[1] = cpu_to_be32(0x08002000);
3571     buf[2] = cpu_to_be32(0x00000000);
3572     buf[3] = cpu_to_be32(0x00000000);
3573     buf[4] = cpu_to_be32(0x000000b2);
3574
3575     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3576     sge_simple->FlagsLength = cpu_to_le32(len |
3577         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3578                           MPI_SGE_FLAGS_END_OF_BUFFER |
3579                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3580                           MPI_SGE_FLAGS_HOST_TO_IOC));
3581     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3582     stm_set_dma_addr(sge_simple->Address, dma_addr);
3583     sge_simple++;
3584     sge_simple->FlagsLength = cpu_to_le32(len |
3585         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3586                           MPI_SGE_FLAGS_LAST_ELEMENT |
3587                           MPI_SGE_FLAGS_END_OF_BUFFER |
3588                           MPI_SGE_FLAGS_END_OF_LIST |
3589                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3590                           MPI_SGE_FLAGS_IOC_TO_HOST));
3591     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3592     stm_set_dma_addr(sge_simple->Address, dma_addr);
3593
3594     priv->ex_link_service_send_pending = 1;
3595
3596     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3597
3598     ret = stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep);
3599
3600         TRACE_EXIT_RES(ret);
3601
3602         return ret;
3603 }
3604
3605 static int
3606 stm_logout_port(MPT_STM_PRIV *priv,
3607                 int port_id, int sleep)
3608 {
3609     MPT_ADAPTER                 *ioc = priv->ioc;
3610     ExLinkServiceSendRequest_t  *req;
3611     MPT_STM_SIMPLE              *sge_simple;
3612     u32                         *buf;
3613     int                         len, ret;
3614     dma_addr_t                  dma_addr;
3615
3616         TRACE_ENTRY();
3617     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3618     memset(req, 0, sizeof(*req));
3619
3620     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3621     req->MsgFlags_Did = cpu_to_le32(port_id);
3622     req->ElsCommandCode = cpu_to_le32(LOGO);
3623
3624     len = 4 * 4;
3625     buf = priv->hw->exlink_buf;
3626     memset(buf, 0, len);
3627
3628     buf[0] = cpu_to_be32(LOGO << 24);
3629     /*
3630      *  the firmware builds the rest of the LOGO payload
3631      */
3632
3633     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3634     sge_simple->FlagsLength = cpu_to_le32(len |
3635         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3636                           MPI_SGE_FLAGS_END_OF_BUFFER |
3637                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3638                           MPI_SGE_FLAGS_HOST_TO_IOC));
3639     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3640     stm_set_dma_addr(sge_simple->Address, dma_addr);
3641     sge_simple++;
3642     sge_simple->FlagsLength = cpu_to_le32(len |
3643         MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_SIMPLE_ELEMENT |
3644                           MPI_SGE_FLAGS_LAST_ELEMENT |
3645                           MPI_SGE_FLAGS_END_OF_BUFFER |
3646                           MPI_SGE_FLAGS_END_OF_LIST |
3647                           MPI_SGE_FLAGS_MPT_STM_ADDRESSING |
3648                           MPI_SGE_FLAGS_IOC_TO_HOST));
3649     dma_addr = priv->hw_dma + ((u8 *)priv->hw->exlink_buf - (u8 *)priv->hw);
3650     stm_set_dma_addr(sge_simple->Address, dma_addr);
3651
3652     priv->ex_link_service_send_pending = 1;
3653
3654     mpt_put_msg_frame(stm_context, _IOC_ID, mf);
3655
3656     ret = stm_wait_for(priv, &priv->ex_link_service_send_pending, 5, sleep);
3657
3658         TRACE_EXIT_RES(ret);
3659
3660         return ret;
3661 }
3662
3663 static int
3664 stm_process_logout_port(MPT_STM_PRIV *priv,
3665                         int port_id, int sleep)
3666 {
3667     MPT_ADAPTER                 *ioc = priv->ioc;
3668     ExLinkServiceSendRequest_t  *req;
3669     MPT_STM_SIMPLE              *sge_simple;
3670     u32                         *buf;
3671     int                         len, ret;
3672     dma_addr_t                  dma_addr;
3673
3674         TRACE_ENTRY();
3675     req = (ExLinkServiceSendRequest_t *)mpt_msg_frame_alloc(ioc,-1);
3676     memset(req, 0, sizeof(*req));
3677
3678     req->Function = MPI_FUNCTION_FC_EX_LINK_SRVC_SEND;
3679     req->MsgFlags_Did = cpu_to_le32(port_id);
3680     req->ElsCommandCode = cpu_to_le32(PRLO);
3681
3682     len = 5 * 4;
3683     buf = priv->hw->exlink_buf;
3684     memset(buf, 0, len);
3685
3686     buf[0] = cpu_to_be32(0x00100014 | (PRLO << 24));
3687     buf[1] = cpu_to_be32(0x08002000);
3688     buf[2] = cpu_to_be32(0x00000000);
3689     buf[3] = cpu_to_be32(0x00000000);
3690     buf[4] = cpu_to_be32(0x00000000);
3691
3692     sge_simple = (MPT_STM_SIMPLE *)&req->SGL;
3693     sge_simple->FlagsLength = cpu_to_le32(len |
3694