OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [ide-scsi.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * linux/drivers/scsi/ide-scsi.c        Version 0.32            May  21, 1998
3
 *
4
 * Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
5
 */
6
 
7
/*
8
 * Emulation of a SCSI host adapter for IDE ATAPI devices.
9
 *
10
 * With this driver, one can use the Linux SCSI drivers instead of the
11
 * native IDE ATAPI drivers.
12
 *
13
 * Ver 0.1   Dec  3 96   Initial version.
14
 * Ver 0.2   Jan 26 97   Fixed bug in cleanup_module() and added emulation
15
 *                        of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks
16
 *                        to Janos Farkas for pointing this out.
17
 *                       Avoid using bitfields in structures for m68k.
18
 *                       Added Scather/Gather and DMA support.
19
 * Ver 0.3   Jul 24 97   Add support for ATAPI PD/CD drives.
20
 * Ver 0.31  Apr  3 98   Remove buggy MODE_SENSE6/MODE_SELECT6 translation.
21
 *                       Add variable irq timeout support.
22
 * Ver 0.32  May 21 98   Perform maximal data transfer when the drive wants
23
 *                        to send us more data than would fit in our buffer.
24
 */
25
 
26
#include <linux/module.h>
27
#include <linux/types.h>
28
#include <linux/string.h>
29
#include <linux/kernel.h>
30
#include <linux/mm.h>
31
#include <linux/ioport.h>
32
#include <linux/blkdev.h>
33
#include <linux/errno.h>
34
#include <linux/hdreg.h>
35
#include <linux/malloc.h>
36
 
37
#include <asm/io.h>
38
#include <asm/bitops.h>
39
 
40
#include "../block/ide.h"
41
 
42
#include "scsi.h"
43
#include "hosts.h"
44
#include "sd.h"
45
#include "ide-scsi.h"
46
 
47
#define IDESCSI_DEBUG_LOG               0
48
 
49
typedef struct idescsi_pc_s {
50
        u8 c[12];                               /* Actual packet bytes */
51
        int request_transfer;                   /* Bytes to transfer */
52
        int actually_transferred;               /* Bytes actually transferred */
53
        int buffer_size;                        /* Size of our data buffer */
54
        struct request *rq;                     /* The corresponding request */
55
        byte *buffer;                           /* Data buffer */
56
        byte *current_position;                 /* Pointer into the above buffer */
57
        struct scatterlist *sg;                 /* Scather gather table */
58
        int b_count;                            /* Bytes transferred from current entry */
59
        Scsi_Cmnd *scsi_cmd;                    /* SCSI command */
60
        void (*done)(Scsi_Cmnd *);              /* Scsi completion routine */
61
        unsigned int flags;                     /* Status/Action flags */
62
        unsigned long timeout;                  /* Command timeout */
63
} idescsi_pc_t;
64
 
65
/*
66
 *      Packet command status bits.
67
 */
68
#define PC_DMA_IN_PROGRESS              0        /* 1 while DMA in progress */
69
#define PC_WRITING                      1       /* Data direction */
70
 
71
typedef struct {
72
        ide_drive_t *drive;
73
        idescsi_pc_t *pc;                       /* Current packet command */
74
        unsigned int flags;                     /* Status/Action flags */
75
        int media;
76
} idescsi_scsi_t;
77
 
78
/*
79
 *      Per ATAPI device status bits.
80
 */
81
#define IDESCSI_DRQ_INTERRUPT           0        /* DRQ interrupt device */
82
 
83
/*
84
 *      ide-scsi requests.
85
 */
86
#define IDESCSI_PC_RQ                   90
87
 
88
/*
89
 *      Bits of the interrupt reason register.
90
 */
91
#define IDESCSI_IREASON_COD     0x1             /* Information transferred is command */
92
#define IDESCSI_IREASON_IO      0x2             /* The device requests us to read */
93
 
94
#define IDE_MIN(a,b)      ((a)<(b) ? (a):(b))
95
#define IDE_MAX(a,b)      ((a)>(b) ? (a):(b))
96
 
97
static void idescsi_discard_data (ide_drive_t *drive, unsigned int bcount)
98
{
99
        while (bcount--)
100
                IN_BYTE (IDE_DATA_REG);
101
}
102
 
103
static void idescsi_output_zeros (ide_drive_t *drive, unsigned int bcount)
104
{
105
        while (bcount--)
106
                OUT_BYTE (0, IDE_DATA_REG);
107
}
108
 
109
/*
110
 *      PIO data transfer routines using the scather gather table.
111
 */
112
static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
113
{
114
        int count;
115
 
116
        while (bcount) {
117
                if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
118
                        printk (KERN_ERR "ide-scsi: scather gather table too small, discarding data\n");
119
                        idescsi_discard_data (drive, bcount);
120
                        return;
121
                }
122
                count = IDE_MIN (pc->sg->length - pc->b_count, bcount);
123
                atapi_input_bytes (drive, pc->sg->address + pc->b_count, count);
124
                bcount -= count; pc->b_count += count;
125
                if (pc->b_count == pc->sg->length) {
126
                        pc->sg++;
127
                        pc->b_count = 0;
128
                }
129
        }
130
}
131
 
132
static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
133
{
134
        int count;
135
 
136
        while (bcount) {
137
                if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
138
                        printk (KERN_ERR "ide-scsi: scather gather table too small, padding with zeros\n");
139
                        idescsi_output_zeros (drive, bcount);
140
                        return;
141
                }
142
                count = IDE_MIN (pc->sg->length - pc->b_count, bcount);
143
                atapi_output_bytes (drive, pc->sg->address + pc->b_count, count);
144
                bcount -= count; pc->b_count += count;
145
                if (pc->b_count == pc->sg->length) {
146
                        pc->sg++;
147
                        pc->b_count = 0;
148
                }
149
        }
150
}
151
 
152
/*
153
 *      Most of the SCSI commands are supported directly by ATAPI devices.
154
 *      idescsi_transform_pc handles the few exceptions.
155
 */
156
static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc)
157
{
158
        idescsi_scsi_t *scsi = drive->scsi;
159
        u8 *c = pc->c;
160
 
161
        if (scsi->media == TYPE_ROM) {
162
                if (c[0] == READ_6 || c[0] == WRITE_6) {
163
                        c[8] = c[4];            c[5] = c[3];            c[4] = c[2];
164
                        c[3] = c[1] & 0x1f;     c[2] = 0;                c[1] &= 0xe0;
165
                        c[0] += (READ_10 - READ_6);
166
                }
167
        }
168
}
169
 
170
static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
171
{
172
        idescsi_scsi_t *scsi = drive->scsi;
173
        u8 *buf = pc->buffer;
174
 
175
        if (scsi->media == TYPE_ROM) {
176
                if (pc->c[0] == INQUIRY)
177
                        buf[2] |= 2;
178
        }
179
}
180
 
181
static inline void idescsi_free_bh (struct buffer_head *bh)
182
{
183
        struct buffer_head *bhp;
184
 
185
        while (bh) {
186
                bhp = bh;
187
                bh = bh->b_reqnext;
188
                kfree (bhp);
189
        }
190
}
191
 
192
void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
193
{
194
        ide_drive_t *drive = hwgroup->drive;
195
        idescsi_scsi_t *scsi = drive->scsi;
196
        struct request *rq = hwgroup->rq;
197
        idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer;
198
 
199
        if (rq->cmd != IDESCSI_PC_RQ) {
200
                ide_end_request (uptodate, hwgroup);
201
                return;
202
        }
203
        ide_end_drive_cmd (drive, 0, 0);
204
        if (rq->errors >= ERROR_MAX) {
205
#if IDESCSI_DEBUG_LOG
206
                printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
207
#endif /* IDESCSI_DEBUG_LOG */
208
                pc->scsi_cmd->result = DID_ERROR << 16;
209
        } else if (rq->errors) {
210
#if IDESCSI_DEBUG_LOG
211
                printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
212
#endif /* IDESCSI_DEBUG_LOG */
213
                pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
214
        } else {
215
#if IDESCSI_DEBUG_LOG
216
                printk ("ide-scsi: %s: success for %lu\n", drive->name, pc->scsi_cmd->serial_number);
217
#endif /* IDESCSI_DEBUG_LOG */
218
                pc->scsi_cmd->result = DID_OK << 16;
219
                idescsi_transform_pc2 (drive, pc);
220
        }
221
        pc->done(pc->scsi_cmd);
222
        idescsi_free_bh (rq->bh);
223
        kfree(pc); kfree(rq);
224
        scsi->pc = NULL;
225
}
226
 
227
static inline unsigned long get_timeout(idescsi_pc_t *pc)
228
{
229
        return IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
230
}
231
 
232
/*
233
 *      Our interrupt handler.
234
 */
235
static void idescsi_pc_intr (ide_drive_t *drive)
236
{
237
        idescsi_scsi_t *scsi = drive->scsi;
238
        byte status, ireason;
239
        int bcount;
240
        idescsi_pc_t *pc=scsi->pc;
241
        struct request *rq = pc->rq;
242
        unsigned int temp;
243
 
244
#if IDESCSI_DEBUG_LOG
245
        printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n");
246
#endif /* IDESCSI_DEBUG_LOG */
247
 
248
        if (clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
249
#if IDESCSI_DEBUG_LOG
250
                printk ("ide-scsi: %s: DMA complete\n", drive->name);
251
#endif /* IDESCSI_DEBUG_LOG */
252
                pc->actually_transferred=pc->request_transfer;
253
                (void) (HWIF(drive)->dmaproc(ide_dma_abort, drive));
254
        }
255
 
256
        status = GET_STAT();                                            /* Clear the interrupt */
257
 
258
        if ((status & DRQ_STAT) == 0) {                                  /* No more interrupts */
259
#if IDESCSI_DEBUG_LOG
260
                printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred);
261
#endif /* IDESCSI_DEBUG_LOG */
262
                sti();
263
                if (status & ERR_STAT)
264
                        rq->errors++;
265
                idescsi_end_request (1, HWGROUP(drive));
266
                return;
267
        }
268
        bcount = IN_BYTE (IDE_BCOUNTH_REG) << 8 | IN_BYTE (IDE_BCOUNTL_REG);
269
        ireason = IN_BYTE (IDE_IREASON_REG);
270
 
271
        if (ireason & IDESCSI_IREASON_COD) {
272
                printk (KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
273
                ide_do_reset (drive);
274
                return;
275
        }
276
        if (ireason & IDESCSI_IREASON_IO) {
277
                temp = pc->actually_transferred + bcount;
278
                if ( temp > pc->request_transfer) {
279
                        if (temp > pc->buffer_size) {
280
                                printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
281
                                temp = pc->buffer_size - pc->actually_transferred;
282
                                if (temp) {
283
                                        clear_bit(PC_WRITING, &pc->flags);
284
                                        if (pc->sg)
285
                                                idescsi_input_buffers(drive, pc, temp);
286
                                        else
287
                                                atapi_input_bytes(drive, pc->current_position, temp);
288
                                        printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount);
289
                                }
290
                                pc->actually_transferred += temp;
291
                                pc->current_position += temp;
292
                                idescsi_discard_data (drive,bcount - temp);
293
                                ide_set_handler (drive, &idescsi_pc_intr, get_timeout(pc));
294
                                return;
295
                        }
296
#if IDESCSI_DEBUG_LOG
297
                        printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
298
#endif /* IDESCSI_DEBUG_LOG */
299
                }
300
        }
301
        if (ireason & IDESCSI_IREASON_IO) {
302
                if (pc->sg)
303
                        idescsi_input_buffers (drive, pc, bcount);
304
                else
305
                        atapi_input_bytes (drive,pc->current_position,bcount);
306
        } else {
307
                if (pc->sg)
308
                        idescsi_output_buffers (drive, pc, bcount);
309
                else
310
                        atapi_output_bytes (drive,pc->current_position,bcount);
311
        }
312
        pc->actually_transferred+=bcount;                               /* Update the current position */
313
        pc->current_position+=bcount;
314
 
315
        ide_set_handler (drive,&idescsi_pc_intr,get_timeout(pc));       /* And set the interrupt handler again */
316
}
317
 
318
static void idescsi_transfer_pc (ide_drive_t *drive)
319
{
320
        idescsi_scsi_t *scsi = drive->scsi;
321
        idescsi_pc_t *pc=scsi->pc;
322
        byte ireason;
323
 
324
        if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
325
                printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n");
326
                return;
327
        }
328
        ireason = IN_BYTE (IDE_IREASON_REG);
329
        if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
330
                printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
331
                ide_do_reset (drive);
332
                return;
333
        }
334
        ide_set_handler (drive, &idescsi_pc_intr, get_timeout(pc));     /* Set the interrupt routine */
335
        atapi_output_bytes (drive, scsi->pc->c, 12);                    /* Send the actual packet */
336
}
337
 
338
/*
339
 *      Issue a packet command
340
 */
341
static void idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
342
{
343
        idescsi_scsi_t *scsi = drive->scsi;
344
        int bcount;
345
        struct request *rq = pc->rq;
346
        int dma_ok = 0;
347
 
348
        scsi->pc=pc;                                                    /* Set the current packet command */
349
        pc->actually_transferred=0;                                      /* We haven't transferred any data yet */
350
        pc->current_position=pc->buffer;
351
        bcount = IDE_MIN (pc->request_transfer, 63 * 1024);             /* Request to transfer the entire buffer at once */
352
 
353
        if (drive->using_dma && rq->bh)
354
                dma_ok=!HWIF(drive)->dmaproc(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive);
355
 
356
        OUT_BYTE (drive->ctl,IDE_CONTROL_REG);
357
        OUT_BYTE (dma_ok,IDE_FEATURE_REG);
358
        OUT_BYTE (bcount >> 8,IDE_BCOUNTH_REG);
359
        OUT_BYTE (bcount & 0xff,IDE_BCOUNTL_REG);
360
        OUT_BYTE (drive->select.all,IDE_SELECT_REG);
361
 
362
        if (dma_ok) {
363
                set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
364
                (void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
365
        }
366
        if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
367
                ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc));
368
                OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);              /* Issue the packet command */
369
        } else {
370
                OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
371
                idescsi_transfer_pc (drive);
372
        }
373
}
374
 
375
/*
376
 *      idescsi_do_request is our request handling function.
377
 */
378
void idescsi_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
379
{
380
#if IDESCSI_DEBUG_LOG
381
        printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
382
        printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
383
#endif /* IDESCSI_DEBUG_LOG */
384
 
385
        if (rq->cmd == IDESCSI_PC_RQ) {
386
                idescsi_issue_pc (drive, (idescsi_pc_t *) rq->buffer);
387
                return;
388
        }
389
        printk (KERN_ERR "ide-scsi: %s: unsupported command in request queue (%x)\n", drive->name, rq->cmd);
390
        idescsi_end_request (0,HWGROUP (drive));
391
}
392
 
393
int idescsi_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
394
{
395
        MOD_INC_USE_COUNT;
396
        return 0;
397
}
398
 
399
void idescsi_ide_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
400
{
401
        MOD_DEC_USE_COUNT;
402
}
403
 
404
static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES];
405
static int idescsi_initialized = 0;
406
 
407
int idescsi_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
408
{
409
        return -EINVAL;
410
}
411
 
412
static struct proc_dir_entry idescsi_proc_dir = {PROC_SCSI_IDESCSI, 8, "ide-scsi", S_IFDIR | S_IRUGO | S_IXUGO, 2};
413
 
414
/*
415
 *      idescsi_setup will register the driver for each scsi.
416
 */
417
void idescsi_setup (ide_drive_t *drive)
418
{
419
        idescsi_scsi_t *scsi;
420
        int i, id;
421
 
422
        if (!idescsi_initialized) {
423
                idescsi_initialized = 1;
424
                for (i = 0; i < MAX_HWIFS * MAX_DRIVES; i++)
425
                        idescsi_drives[i] = NULL;
426
        }
427
        if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
428
                printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
429
                return;
430
        }
431
        for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
432
        idescsi_drives[id] = drive;
433
        drive->scsi = scsi;
434
        drive->ready_stat = 0;
435
        memset (scsi, 0, sizeof (idescsi_scsi_t));
436
        scsi->drive = drive;
437
        scsi->media = (drive->id->config >> 8) & 0x1f;
438
        if (drive->id && (drive->id->config & 0x0060) == 0x20)
439
                set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags);
440
        printk ("ATAPI overlap supported: %s\n",
441
                drive->id->capability & 0x20 ? "Yes" : "No");
442
}
443
 
444
int idescsi_detect (Scsi_Host_Template *host_template)
445
{
446
        struct Scsi_Host *host;
447
        int id;
448
 
449
        host_template->proc_dir = &idescsi_proc_dir;
450
        host = scsi_register(host_template, 0);
451
        for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++);
452
        host->max_id = id;
453
        host->can_queue = host->cmd_per_lun * id;
454
        return 1;
455
}
456
 
457
int idescsi_release (struct Scsi_Host *host)
458
{
459
        return 0;
460
}
461
 
462
const char *idescsi_info (struct Scsi_Host *host)
463
{
464
        return "SCSI host adapter emulation for IDE ATAPI devices";
465
}
466
 
467
static inline struct buffer_head *idescsi_kmalloc_bh (int count)
468
{
469
        struct buffer_head *bh, *bhp, *first_bh;
470
 
471
        if ((first_bh = bhp = bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL)
472
                goto abort;
473
        memset (bh, 0, sizeof (struct buffer_head));
474
        bh->b_reqnext = NULL;
475
        while (--count) {
476
                if ((bh = kmalloc (sizeof(struct buffer_head), GFP_ATOMIC)) == NULL)
477
                        goto abort;
478
                memset (bh, 0, sizeof (struct buffer_head));
479
                bhp->b_reqnext = bh;
480
                bhp = bh;
481
                bh->b_reqnext = NULL;
482
        }
483
        return first_bh;
484
abort:
485
        idescsi_free_bh (first_bh);
486
        return NULL;
487
}
488
 
489
static inline int idescsi_set_direction (idescsi_pc_t *pc)
490
{
491
        switch (pc->c[0]) {
492
                case READ_6: case READ_10: case READ_12:
493
                        clear_bit (PC_WRITING, &pc->flags);
494
                        return 0;
495
                case WRITE_6: case WRITE_10: case WRITE_12:
496
                        set_bit (PC_WRITING, &pc->flags);
497
                        return 0;
498
                default:
499
                        return 1;
500
        }
501
}
502
 
503
static inline struct buffer_head *idescsi_dma_bh (ide_drive_t *drive, idescsi_pc_t *pc)
504
{
505
        struct buffer_head *bh = NULL, *first_bh = NULL;
506
        int segments = pc->scsi_cmd->use_sg;
507
        struct scatterlist *sg = pc->scsi_cmd->request_buffer;
508
 
509
        if (!drive->using_dma || pc->request_transfer % 1024)
510
                return NULL;
511
        if (idescsi_set_direction(pc))
512
                return NULL;
513
        if (segments) {
514
                if ((first_bh = bh = idescsi_kmalloc_bh (segments)) == NULL)
515
                        return NULL;
516
#if IDESCSI_DEBUG_LOG
517
                printk ("ide-scsi: %s: building DMA table, %d segments, %dkB total\n", drive->name, segments, pc->request_transfer >> 10);
518
#endif /* IDESCSI_DEBUG_LOG */
519
                while (segments--) {
520
                        bh->b_data = sg->address;
521
                        bh->b_size = sg->length;
522
                        bh = bh->b_reqnext;
523
                        sg++;
524
                }
525
        } else {
526
                if ((first_bh = bh = idescsi_kmalloc_bh (1)) == NULL)
527
                        return NULL;
528
#if IDESCSI_DEBUG_LOG
529
                printk ("ide-scsi: %s: building DMA table for a single buffer (%dkB)\n", drive->name, pc->request_transfer >> 10);
530
#endif /* IDESCSI_DEBUG_LOG */
531
                bh->b_data = pc->scsi_cmd->request_buffer;
532
                bh->b_size = pc->request_transfer;
533
        }
534
        return first_bh;
535
}
536
 
537
int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
538
{
539
        ide_drive_t *drive = idescsi_drives[cmd->target];
540
        struct request *rq = NULL;
541
        idescsi_pc_t *pc = NULL;
542
 
543
#if IDESCSI_DEBUG_LOG
544
        printk ("idescsi_queue called, serial = %lu, cmd[0] = %x, id = %d\n", cmd->serial_number, cmd->cmnd[0], cmd->target);
545
#endif  /* IDESCSI_DEBUG_LOG */
546
 
547
        if (!drive) {
548
                printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target);
549
                goto abort;
550
        }
551
        pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC);
552
        rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
553
        if (rq == NULL || pc == NULL) {
554
                printk (KERN_ERR "ide-scsi: %s: out of memory\n", drive->name);
555
                goto abort;
556
        }
557
 
558
        memset (pc->c, 0, 12);
559
        pc->flags = 0;
560
        pc->rq = rq;
561
        memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
562
        if (cmd->use_sg) {
563
                pc->buffer = NULL;
564
                pc->sg = cmd->request_buffer;
565
        } else {
566
                pc->buffer = cmd->request_buffer;
567
                pc->sg = NULL;
568
        }
569
        pc->b_count = 0;
570
        pc->request_transfer = pc->buffer_size = cmd->request_bufflen;
571
        pc->scsi_cmd = cmd;
572
        pc->done = done;
573
        pc->timeout = jiffies + cmd->timeout_per_command;
574
        idescsi_transform_pc1 (drive, pc);
575
 
576
        ide_init_drive_cmd (rq);
577
        rq->buffer = (char *) pc;
578
        rq->bh = idescsi_dma_bh (drive, pc);
579
        rq->cmd = IDESCSI_PC_RQ;
580
        (void) ide_do_drive_cmd (drive, rq, ide_end);
581
        return 0;
582
abort:
583
        if (pc) kfree (pc);
584
        if (rq) kfree (rq);
585
        cmd->result = DID_ERROR << 16;
586
        done(cmd);
587
        return 0;
588
}
589
 
590
int idescsi_abort (Scsi_Cmnd *cmd)
591
{
592
        return SCSI_ABORT_SNOOZE;
593
}
594
 
595
int idescsi_reset (Scsi_Cmnd *cmd, unsigned int resetflags)
596
{
597
        return SCSI_RESET_PUNT;
598
}
599
 
600
int idescsi_bios (Disk *disk, kdev_t dev, int *parm)
601
{
602
        ide_drive_t *drive = idescsi_drives[disk->device->id];
603
 
604
        if (drive->cyl && drive->head && drive->sect) {
605
                parm[0] = drive->head;
606
                parm[1] = drive->sect;
607
                parm[2] = drive->cyl;
608
        }
609
        return 0;
610
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.