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