~ubuntu-branches/ubuntu/karmic/linux-ports/karmic

« back to all changes in this revision

Viewing changes to drivers/misc/sgi-gru/grukservices.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich, Luke Yelavich, Michael Casadevall, Tim Gardner, Upstream Kernel Changes
  • Date: 2009-05-06 18:18:55 UTC
  • Revision ID: james.westby@ubuntu.com-20090506181855-t00baeevpnvd9o7a
Tags: 2.6.30-1.1
[ Luke Yelavich ]
* initial release for karmic
* SAUCE: rebase-ports - adjust for the karmic ports kernel
* SAUCE: rebase-ports - also remove abi dirs/files on rebase
* Update configs after rebase against mainline Jaunty tree
* [Config] Disable CONFIG_BLK_DEV_UB and CONFIG_USB_LIBUSUAL as per
  mainline jaunty
* forward-port patch to drbd for powerpc compilation
* [Config] disable CONFIG_LENOVO_SL_LAPTOP for i386 due to FTBFS
* add .o files found in arch/powerpc/lib to all powerpc kernel header
  packages
* [Config] enable CONFIG_DRM_I915_KMS for i386 as per karmic mainline

[ Michael Casadevall ]

* Disable kgdb on sparc64
* [sparc] [Config] Disable GPIO LEDS
* [ia64] Rename -ia64-generic to -ia64 in line with other architectures
* Correct kernel image path for sparc builds
* [hppa] Fix HPPA config files to build modules for all udebian

Rebase on top of karmic mainline 2.6.30-1.1

[ Tim Gardner ]

* [Config] armel: disable staging drivers, fixes FTBS
* [Config] armel imx51: Disable CONFIG_MTD_NAND_MXC, fixes FTBS

[ Upstream Kernel Changes ]

* mpt2sas: Change reset_type enum to avoid namespace collision.
  Submitted upstream.

* Initial release after rebasing against v2.6.30-rc3

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
 */
53
53
 
54
54
/* Blade percpu resources PERMANENTLY reserved for kernel use */
55
 
#define GRU_NUM_KERNEL_CBR      1
 
55
#define GRU_NUM_KERNEL_CBR      1
56
56
#define GRU_NUM_KERNEL_DSR_BYTES 256
 
57
#define GRU_NUM_KERNEL_DSR_CL   (GRU_NUM_KERNEL_DSR_BYTES /             \
 
58
                                        GRU_CACHE_LINE_BYTES)
57
59
#define KERNEL_CTXNUM           15
58
60
 
59
61
/* GRU instruction attributes for all instructions */
94
96
        char    fill;
95
97
};
96
98
 
97
 
#define QLINES(mq)      ((mq) + offsetof(struct message_queue, qlines))
98
99
#define HSTATUS(mq, h)  ((mq) + offsetof(struct message_queue, hstatus[h]))
99
100
 
100
101
static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
122
123
        struct gru_control_block_extended *cbe;
123
124
 
124
125
        cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
125
 
        prefetchw(cbe);         /* Harmless on hardware, required for emulator */
 
126
        prefetchw(cbe); /* Harmless on hardware, required for emulator */
126
127
        excdet->opc = cbe->opccpy;
127
128
        excdet->exopc = cbe->exopccpy;
128
129
        excdet->ecause = cbe->ecause;
250
251
 * Create a message queue.
251
252
 *      qlines - message queue size in cache lines. Includes 2-line header.
252
253
 */
253
 
int gru_create_message_queue(void *p, unsigned int bytes)
 
254
int gru_create_message_queue(struct gru_message_queue_desc *mqd,
 
255
                void *p, unsigned int bytes, int nasid, int vector, int apicid)
254
256
{
255
257
        struct message_queue *mq = p;
256
258
        unsigned int qlines;
265
267
        mq->hstatus[0] = 0;
266
268
        mq->hstatus[1] = 1;
267
269
        mq->head = gru_mesq_head(2, qlines / 2 + 1);
 
270
        mqd->mq = mq;
 
271
        mqd->mq_gpa = uv_gpa(mq);
 
272
        mqd->qlines = qlines;
 
273
        mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
 
274
        mqd->interrupt_vector = vector;
 
275
        mqd->interrupt_apicid = apicid;
268
276
        return 0;
269
277
}
270
278
EXPORT_SYMBOL_GPL(gru_create_message_queue);
277
285
 *              -1 - if mesq sent successfully but queue not full
278
286
 *              >0 - unexpected error. MQE_xxx returned
279
287
 */
280
 
static int send_noop_message(void *cb,
281
 
                                unsigned long mq, void *mesg)
 
288
static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
 
289
                                void *mesg)
282
290
{
283
291
        const struct message_header noop_header = {
284
292
                                        .present = MQS_NOOP, .lines = 1};
289
297
        STAT(mesq_noop);
290
298
        save_mhdr = *mhdr;
291
299
        *mhdr = noop_header;
292
 
        gru_mesq(cb, mq, gru_get_tri(mhdr), 1, IMA);
 
300
        gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA);
293
301
        ret = gru_wait(cb);
294
302
 
295
303
        if (ret) {
313
321
                        break;
314
322
                case CBSS_PUT_NACKED:
315
323
                        STAT(mesq_noop_put_nacked);
316
 
                        m = mq + (gru_get_amo_value_head(cb) << 6);
 
324
                        m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
317
325
                        gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1,
318
326
                                                IMA);
319
327
                        if (gru_wait(cb) == CBS_IDLE)
333
341
/*
334
342
 * Handle a gru_mesq full.
335
343
 */
336
 
static int send_message_queue_full(void *cb,
337
 
                           unsigned long mq, void *mesg, int lines)
 
344
static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
 
345
                                void *mesg, int lines)
338
346
{
339
347
        union gru_mesqhead mqh;
340
348
        unsigned int limit, head;
341
349
        unsigned long avalue;
342
 
        int half, qlines, save;
 
350
        int half, qlines;
343
351
 
344
352
        /* Determine if switching to first/second half of q */
345
353
        avalue = gru_get_amo_value(cb);
346
354
        head = gru_get_amo_value_head(cb);
347
355
        limit = gru_get_amo_value_limit(cb);
348
356
 
349
 
        /*
350
 
         * Fetch "qlines" from the queue header. Since the queue may be
351
 
         * in memory that can't be accessed using socket addresses, use
352
 
         * the GRU to access the data. Use DSR space from the message.
353
 
         */
354
 
        save = *(int *)mesg;
355
 
        gru_vload(cb, QLINES(mq), gru_get_tri(mesg), XTYPE_W, 1, 1, IMA);
356
 
        if (gru_wait(cb) != CBS_IDLE)
357
 
                goto cberr;
358
 
        qlines = *(int *)mesg;
359
 
        *(int *)mesg = save;
 
357
        qlines = mqd->qlines;
360
358
        half = (limit != qlines);
361
359
 
362
360
        if (half)
365
363
                mqh = gru_mesq_head(2, qlines / 2 + 1);
366
364
 
367
365
        /* Try to get lock for switching head pointer */
368
 
        gru_gamir(cb, EOP_IR_CLR, HSTATUS(mq, half), XTYPE_DW, IMA);
 
366
        gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA);
369
367
        if (gru_wait(cb) != CBS_IDLE)
370
368
                goto cberr;
371
369
        if (!gru_get_amo_value(cb)) {
375
373
 
376
374
        /* Got the lock. Send optional NOP if queue not full, */
377
375
        if (head != limit) {
378
 
                if (send_noop_message(cb, mq, mesg)) {
379
 
                        gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half),
 
376
                if (send_noop_message(cb, mqd, mesg)) {
 
377
                        gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half),
380
378
                                        XTYPE_DW, IMA);
381
379
                        if (gru_wait(cb) != CBS_IDLE)
382
380
                                goto cberr;
387
385
        }
388
386
 
389
387
        /* Then flip queuehead to other half of queue. */
390
 
        gru_gamer(cb, EOP_ERR_CSWAP, mq, XTYPE_DW, mqh.val, avalue, IMA);
 
388
        gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue,
 
389
                                                        IMA);
391
390
        if (gru_wait(cb) != CBS_IDLE)
392
391
                goto cberr;
393
392
 
394
393
        /* If not successfully in swapping queue head, clear the hstatus lock */
395
394
        if (gru_get_amo_value(cb) != avalue) {
396
395
                STAT(mesq_qf_switch_head_failed);
397
 
                gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA);
 
396
                gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW,
 
397
                                                        IMA);
398
398
                if (gru_wait(cb) != CBS_IDLE)
399
399
                        goto cberr;
400
400
        }
404
404
        return MQE_UNEXPECTED_CB_ERR;
405
405
}
406
406
 
 
407
/*
 
408
 * Send a cross-partition interrupt to the SSI that contains the target
 
409
 * message queue. Normally, the interrupt is automatically delivered by hardware
 
410
 * but some error conditions require explicit delivery.
 
411
 */
 
412
static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
 
413
{
 
414
        if (mqd->interrupt_vector)
 
415
                uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid,
 
416
                                mqd->interrupt_vector);
 
417
}
 
418
 
407
419
 
408
420
/*
409
421
 * Handle a gru_mesq failure. Some of these failures are software recoverable
410
422
 * or retryable.
411
423
 */
412
 
static int send_message_failure(void *cb,
413
 
                                unsigned long mq,
414
 
                                void *mesg,
415
 
                                int lines)
 
424
static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
 
425
                                void *mesg, int lines)
416
426
{
417
427
        int substatus, ret = 0;
418
428
        unsigned long m;
429
439
                break;
430
440
        case CBSS_QLIMIT_REACHED:
431
441
                STAT(mesq_send_qlimit_reached);
432
 
                ret = send_message_queue_full(cb, mq, mesg, lines);
 
442
                ret = send_message_queue_full(cb, mqd, mesg, lines);
433
443
                break;
434
444
        case CBSS_AMO_NACKED:
435
445
                STAT(mesq_send_amo_nacked);
437
447
                break;
438
448
        case CBSS_PUT_NACKED:
439
449
                STAT(mesq_send_put_nacked);
440
 
                m =mq + (gru_get_amo_value_head(cb) << 6);
 
450
                m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
441
451
                gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
442
 
                if (gru_wait(cb) == CBS_IDLE)
 
452
                if (gru_wait(cb) == CBS_IDLE) {
443
453
                        ret = MQE_OK;
444
 
                else
 
454
                        send_message_queue_interrupt(mqd);
 
455
                } else {
445
456
                        ret = MQE_UNEXPECTED_CB_ERR;
 
457
                }
446
458
                break;
447
459
        default:
448
460
                BUG();
452
464
 
453
465
/*
454
466
 * Send a message to a message queue
455
 
 *      cb      GRU control block to use to send message
456
 
 *      mq      message queue
 
467
 *      mqd     message queue descriptor
457
468
 *      mesg    message. ust be vaddr within a GSEG
458
469
 *      bytes   message size (<= 2 CL)
459
470
 */
460
 
int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
 
471
int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg,
 
472
                                unsigned int bytes)
461
473
{
462
474
        struct message_header *mhdr;
463
475
        void *cb;
481
493
 
482
494
        do {
483
495
                ret = MQE_OK;
484
 
                gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA);
 
496
                gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA);
485
497
                istatus = gru_wait(cb);
486
498
                if (istatus != CBS_IDLE)
487
 
                        ret = send_message_failure(cb, mq, dsr, clines);
 
499
                        ret = send_message_failure(cb, mqd, dsr, clines);
488
500
        } while (ret == MQIE_AGAIN);
489
501
        gru_free_cpu_resources(cb, dsr);
490
502
 
497
509
/*
498
510
 * Advance the receive pointer for the queue to the next message.
499
511
 */
500
 
void gru_free_message(void *rmq, void *mesg)
 
512
void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg)
501
513
{
502
 
        struct message_queue *mq = rmq;
 
514
        struct message_queue *mq = mqd->mq;
503
515
        struct message_header *mhdr = mq->next;
504
516
        void *next, *pnext;
505
517
        int half = -1;
529
541
 * present. User must call next_message() to move to next message.
530
542
 *      rmq     message queue
531
543
 */
532
 
void *gru_get_next_message(void *rmq)
 
544
void *gru_get_next_message(struct gru_message_queue_desc *mqd)
533
545
{
534
 
        struct message_queue *mq = rmq;
 
546
        struct message_queue *mq = mqd->mq;
535
547
        struct message_header *mhdr = mq->next;
536
548
        int present = mhdr->present;
537
549
 
538
550
        /* skip NOOP messages */
539
551
        STAT(mesq_receive);
540
552
        while (present == MQS_NOOP) {
541
 
                gru_free_message(rmq, mhdr);
 
553
                gru_free_message(mqd, mhdr);
542
554
                mhdr = mq->next;
543
555
                present = mhdr->present;
544
556
        }
576
588
        if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
577
589
                return MQE_BUG_NO_RESOURCES;
578
590
        gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
579
 
                  XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_BYTES, IMA);
 
591
                  XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA);
580
592
        ret = gru_wait(cb);
581
593
        gru_free_cpu_resources(cb, dsr);
582
594
        return ret;
611
623
 
612
624
        if (word0 != word1 || word0 != MAGIC) {
613
625
                printk
614
 
                    ("GRU quicktest err: gru %d, found 0x%lx, expected 0x%lx\n",
 
626
                    ("GRU quicktest err: gid %d, found 0x%lx, expected 0x%lx\n",
615
627
                     gru->gs_gid, word1, MAGIC);
616
628
                BUG();          /* ZZZ should not be fatal */
617
629
        }
660
672
        cch->tlb_int_enable = 0;
661
673
        cch->tfm_done_bit_enable = 0;
662
674
        cch->unmap_enable = 1;
663
 
        err = cch_allocate(cch, 0, cbr_map, dsr_map);
 
675
        err = cch_allocate(cch, 0, 0, cbr_map, dsr_map);
664
676
        if (err) {
665
677
                gru_dbg(grudev,
666
 
                        "Unable to allocate kernel CCH: gru %d, err %d\n",
 
678
                        "Unable to allocate kernel CCH: gid %d, err %d\n",
667
679
                        gru->gs_gid, err);
668
680
                BUG();
669
681
        }
670
682
        if (cch_start(cch)) {
671
 
                gru_dbg(grudev, "Unable to start kernel CCH: gru %d, err %d\n",
 
683
                gru_dbg(grudev, "Unable to start kernel CCH: gid %d, err %d\n",
672
684
                        gru->gs_gid, err);
673
685
                BUG();
674
686
        }
678
690
                quicktest(gru);
679
691
        return 0;
680
692
}
 
693
 
 
694
void gru_kservices_exit(struct gru_state *gru)
 
695
{
 
696
        struct gru_context_configuration_handle *cch;
 
697
        struct gru_blade_state *bs;
 
698
 
 
699
        bs = gru->gs_blade;
 
700
        if (gru != &bs->bs_grus[1])
 
701
                return;
 
702
 
 
703
        cch = get_cch(gru->gs_gru_base_vaddr, KERNEL_CTXNUM);
 
704
        lock_cch_handle(cch);
 
705
        if (cch_interrupt_sync(cch))
 
706
                BUG();
 
707
        if (cch_deallocate(cch))
 
708
                BUG();
 
709
        unlock_cch_handle(cch);
 
710
}
 
711