~ubuntu-branches/ubuntu/natty/linux-fsl-imx51/natty

« back to all changes in this revision

Viewing changes to drivers/scsi/qla4xxx/ql4_iocb.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner
  • Date: 2009-08-17 08:29:47 UTC
  • Revision ID: james.westby@ubuntu.com-20090817082947-q3fjbfrs57ct6ixj
Tags: 2.6.31-100.3
* UBUNTU: [Config] Produce headers packages of the form linux-headers-2.6.31-ABI
* UBUNTU: Bump ABI to 100 in order to avoid collisions with other kernel packages
* UBUNTU: [Config] Removed libc-dev from the control file
* UBUNTU: [Config] Implement abstracted debian build for fsl-imx51

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include "ql4_dbg.h"
11
11
#include "ql4_inline.h"
12
12
 
13
 
 
14
13
#include <scsi/scsi_tcq.h>
15
14
 
 
15
static int
 
16
qla4xxx_space_in_req_ring(struct scsi_qla_host *ha, uint16_t req_cnt)
 
17
{
 
18
        uint16_t cnt;
 
19
 
 
20
        /* Calculate number of free request entries. */
 
21
        if ((req_cnt + 2) >= ha->req_q_count) {
 
22
                cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
 
23
                if (ha->request_in < cnt)
 
24
                        ha->req_q_count = cnt - ha->request_in;
 
25
                else
 
26
                        ha->req_q_count = REQUEST_QUEUE_DEPTH -
 
27
                                                (ha->request_in - cnt);
 
28
        }
 
29
 
 
30
        /* Check if room for request in request ring. */
 
31
        if ((req_cnt + 2) < ha->req_q_count)
 
32
                return 1;
 
33
        else
 
34
                return 0;
 
35
}
 
36
 
 
37
static void qla4xxx_advance_req_ring_ptr(struct scsi_qla_host *ha)
 
38
{
 
39
        /* Advance request queue pointer */
 
40
        if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) {
 
41
                ha->request_in = 0;
 
42
                ha->request_ptr = ha->request_ring;
 
43
        } else {
 
44
                ha->request_in++;
 
45
                ha->request_ptr++;
 
46
        }
 
47
}
 
48
 
16
49
/**
17
50
 * qla4xxx_get_req_pkt - returns a valid entry in request queue.
18
51
 * @ha: Pointer to host adapter structure.
26
59
static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
27
60
                               struct queue_entry **queue_entry)
28
61
{
29
 
        uint16_t request_in;
30
 
        uint8_t status = QLA_SUCCESS;
31
 
 
32
 
        *queue_entry = ha->request_ptr;
33
 
 
34
 
        /* get the latest request_in and request_out index */
35
 
        request_in = ha->request_in;
36
 
        ha->request_out = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
37
 
 
38
 
        /* Advance request queue pointer and check for queue full */
39
 
        if (request_in == (REQUEST_QUEUE_DEPTH - 1)) {
40
 
                request_in = 0;
41
 
                ha->request_ptr = ha->request_ring;
42
 
        } else {
43
 
                request_in++;
44
 
                ha->request_ptr++;
45
 
        }
46
 
 
47
 
        /* request queue is full, try again later */
48
 
        if ((ha->iocb_cnt + 1) >= ha->iocb_hiwat) {
49
 
                /* restore request pointer */
50
 
                ha->request_ptr = *queue_entry;
51
 
                status = QLA_ERROR;
52
 
        } else {
53
 
                ha->request_in = request_in;
 
62
        uint16_t req_cnt = 1;
 
63
 
 
64
        if (qla4xxx_space_in_req_ring(ha, req_cnt)) {
 
65
                *queue_entry = ha->request_ptr;
54
66
                memset(*queue_entry, 0, sizeof(**queue_entry));
 
67
 
 
68
                qla4xxx_advance_req_ring_ptr(ha);
 
69
                ha->req_q_count -= req_cnt;
 
70
                return QLA_SUCCESS;
55
71
        }
56
72
 
57
 
        return status;
 
73
        return QLA_ERROR;
58
74
}
59
75
 
60
76
/**
100
116
        return status;
101
117
}
102
118
 
103
 
static struct continuation_t1_entry* qla4xxx_alloc_cont_entry(
104
 
        struct scsi_qla_host *ha)
 
119
static struct continuation_t1_entry *
 
120
qla4xxx_alloc_cont_entry(struct scsi_qla_host *ha)
105
121
{
106
122
        struct continuation_t1_entry *cont_entry;
107
123
 
108
124
        cont_entry = (struct continuation_t1_entry *)ha->request_ptr;
109
125
 
110
 
        /* Advance request queue pointer */
111
 
        if (ha->request_in == (REQUEST_QUEUE_DEPTH - 1)) {
112
 
                ha->request_in = 0;
113
 
                ha->request_ptr = ha->request_ring;
114
 
        } else {
115
 
                ha->request_in++;
116
 
                ha->request_ptr++;
117
 
        }
 
126
        qla4xxx_advance_req_ring_ptr(ha);
118
127
 
119
128
        /* Load packet defaults */
120
129
        cont_entry->hdr.entryType = ET_CONTINUE;
197
206
        struct scsi_cmnd *cmd = srb->cmd;
198
207
        struct ddb_entry *ddb_entry;
199
208
        struct command_t3_entry *cmd_entry;
200
 
 
201
209
        int nseg;
202
210
        uint16_t tot_dsds;
203
211
        uint16_t req_cnt;
204
 
 
205
212
        unsigned long flags;
206
 
        uint16_t cnt;
207
213
        uint32_t index;
208
214
        char tag[2];
209
215
 
217
223
 
218
224
        index = (uint32_t)cmd->request->tag;
219
225
 
 
226
        /*
 
227
         * Check to see if adapter is online before placing request on
 
228
         * request queue.  If a reset occurs and a request is in the queue,
 
229
         * the firmware will still attempt to process the request, retrieving
 
230
         * garbage for pointers.
 
231
         */
 
232
        if (!test_bit(AF_ONLINE, &ha->flags)) {
 
233
                DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! "
 
234
                              "Do not issue command.\n",
 
235
                              ha->host_no, __func__));
 
236
                goto queuing_error;
 
237
        }
 
238
 
220
239
        /* Calculate the number of request entries needed. */
221
240
        nseg = scsi_dma_map(cmd);
222
241
        if (nseg < 0)
224
243
        tot_dsds = nseg;
225
244
 
226
245
        req_cnt = qla4xxx_calc_request_entries(tot_dsds);
227
 
 
228
 
        if (ha->req_q_count < (req_cnt + 2)) {
229
 
                cnt = (uint16_t) le32_to_cpu(ha->shadow_regs->req_q_out);
230
 
                if (ha->request_in < cnt)
231
 
                        ha->req_q_count = cnt - ha->request_in;
232
 
                else
233
 
                        ha->req_q_count = REQUEST_QUEUE_DEPTH -
234
 
                                (ha->request_in - cnt);
235
 
        }
236
 
 
237
 
        if (ha->req_q_count < (req_cnt + 2))
 
246
        if (!qla4xxx_space_in_req_ring(ha, req_cnt))
238
247
                goto queuing_error;
239
248
 
240
249
        /* total iocbs active */
286
295
                        break;
287
296
                }
288
297
 
289
 
 
290
 
        /* Advance request queue pointer */
291
 
        ha->request_in++;
292
 
        if (ha->request_in == REQUEST_QUEUE_DEPTH) {
293
 
                ha->request_in = 0;
294
 
                ha->request_ptr = ha->request_ring;
295
 
        } else
296
 
                ha->request_ptr++;
297
 
 
298
 
 
 
298
        qla4xxx_advance_req_ring_ptr(ha);
299
299
        qla4xxx_build_scsi_iocbs(srb, cmd_entry, tot_dsds);
300
300
        wmb();
301
301
 
302
 
        /*
303
 
         * Check to see if adapter is online before placing request on
304
 
         * request queue.  If a reset occurs and a request is in the queue,
305
 
         * the firmware will still attempt to process the request, retrieving
306
 
         * garbage for pointers.
307
 
         */
308
 
        if (!test_bit(AF_ONLINE, &ha->flags)) {
309
 
                DEBUG2(printk("scsi%ld: %s: Adapter OFFLINE! "
310
 
                              "Do not issue command.\n",
311
 
                              ha->host_no, __func__));
312
 
                goto queuing_error;
313
 
        }
314
 
 
315
302
        srb->cmd->host_scribble = (unsigned char *)srb;
316
303
 
317
304
        /* update counters */