@@ -58,8 +58,15 @@ struct aha1542_hostdata {
58
58
int aha1542_last_mbi_used ;
59
59
int aha1542_last_mbo_used ;
60
60
struct scsi_cmnd * int_cmds [AHA1542_MAILBOXES ];
61
- struct mailbox mb [2 * AHA1542_MAILBOXES ];
62
- struct ccb ccb [AHA1542_MAILBOXES ];
61
+ struct mailbox * mb ;
62
+ dma_addr_t mb_handle ;
63
+ struct ccb * ccb ;
64
+ dma_addr_t ccb_handle ;
65
+ };
66
+
67
+ struct aha1542_cmd {
68
+ struct chain * chain ;
69
+ dma_addr_t chain_handle ;
63
70
};
64
71
65
72
static inline void aha1542_intr_reset (u16 base )
@@ -233,6 +240,21 @@ static int aha1542_test_port(struct Scsi_Host *sh)
233
240
return 1 ;
234
241
}
235
242
243
+ static void aha1542_free_cmd (struct scsi_cmnd * cmd )
244
+ {
245
+ struct aha1542_cmd * acmd = scsi_cmd_priv (cmd );
246
+ struct device * dev = cmd -> device -> host -> dma_dev ;
247
+ size_t len = scsi_sg_count (cmd ) * sizeof (struct chain );
248
+
249
+ if (acmd -> chain ) {
250
+ dma_unmap_single (dev , acmd -> chain_handle , len , DMA_TO_DEVICE );
251
+ kfree (acmd -> chain );
252
+ }
253
+
254
+ acmd -> chain = NULL ;
255
+ scsi_dma_unmap (cmd );
256
+ }
257
+
236
258
static irqreturn_t aha1542_interrupt (int irq , void * dev_id )
237
259
{
238
260
struct Scsi_Host * sh = dev_id ;
@@ -303,7 +325,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
303
325
return IRQ_HANDLED ;
304
326
};
305
327
306
- mbo = (scsi2int (mb [mbi ].ccbptr ) - ( isa_virt_to_bus ( & ccb [ 0 ])) ) / sizeof (struct ccb );
328
+ mbo = (scsi2int (mb [mbi ].ccbptr ) - aha1542 -> ccb_handle ) / sizeof (struct ccb );
307
329
mbistatus = mb [mbi ].status ;
308
330
mb [mbi ].status = 0 ;
309
331
aha1542 -> aha1542_last_mbi_used = mbi ;
@@ -331,8 +353,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
331
353
return IRQ_HANDLED ;
332
354
}
333
355
my_done = tmp_cmd -> scsi_done ;
334
- kfree (tmp_cmd -> host_scribble );
335
- tmp_cmd -> host_scribble = NULL ;
356
+ aha1542_free_cmd (tmp_cmd );
336
357
/* Fetch the sense data, and tuck it away, in the required slot. The
337
358
Adaptec automatically fetches it, and there is no guarantee that
338
359
we will still have it in the cdb when we come back */
@@ -369,6 +390,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
369
390
370
391
static int aha1542_queuecommand (struct Scsi_Host * sh , struct scsi_cmnd * cmd )
371
392
{
393
+ struct aha1542_cmd * acmd = scsi_cmd_priv (cmd );
372
394
struct aha1542_hostdata * aha1542 = shost_priv (sh );
373
395
u8 direction ;
374
396
u8 target = cmd -> device -> id ;
@@ -378,7 +400,6 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
378
400
int mbo , sg_count ;
379
401
struct mailbox * mb = aha1542 -> mb ;
380
402
struct ccb * ccb = aha1542 -> ccb ;
381
- struct chain * cptr ;
382
403
383
404
if (* cmd -> cmnd == REQUEST_SENSE ) {
384
405
/* Don't do the command - we have the sense data already */
@@ -398,15 +419,17 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
398
419
print_hex_dump_bytes ("command: " , DUMP_PREFIX_NONE , cmd -> cmnd , cmd -> cmd_len );
399
420
}
400
421
#endif
401
- if (bufflen ) { /* allocate memory before taking host_lock */
402
- sg_count = scsi_sg_count (cmd );
403
- cptr = kmalloc_array (sg_count , sizeof (* cptr ),
404
- GFP_KERNEL | GFP_DMA );
405
- if (!cptr )
406
- return SCSI_MLQUEUE_HOST_BUSY ;
407
- } else {
408
- sg_count = 0 ;
409
- cptr = NULL ;
422
+ sg_count = scsi_dma_map (cmd );
423
+ if (sg_count ) {
424
+ size_t len = sg_count * sizeof (struct chain );
425
+
426
+ acmd -> chain = kmalloc (len , GFP_DMA );
427
+ if (!acmd -> chain )
428
+ goto out_unmap ;
429
+ acmd -> chain_handle = dma_map_single (sh -> dma_dev , acmd -> chain ,
430
+ len , DMA_TO_DEVICE );
431
+ if (dma_mapping_error (sh -> dma_dev , acmd -> chain_handle ))
432
+ goto out_free_chain ;
410
433
}
411
434
412
435
/* Use the outgoing mailboxes in a round-robin fashion, because this
@@ -437,7 +460,8 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
437
460
shost_printk (KERN_DEBUG , sh , "Sending command (%d %p)..." , mbo , cmd -> scsi_done );
438
461
#endif
439
462
440
- any2scsi (mb [mbo ].ccbptr , isa_virt_to_bus (& ccb [mbo ])); /* This gets trashed for some reason */
463
+ /* This gets trashed for some reason */
464
+ any2scsi (mb [mbo ].ccbptr , aha1542 -> ccb_handle + mbo * sizeof (* ccb ));
441
465
442
466
memset (& ccb [mbo ], 0 , sizeof (struct ccb ));
443
467
@@ -456,21 +480,18 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
456
480
int i ;
457
481
458
482
ccb [mbo ].op = 2 ; /* SCSI Initiator Command w/scatter-gather */
459
- cmd -> host_scribble = (void * )cptr ;
460
483
scsi_for_each_sg (cmd , sg , sg_count , i ) {
461
- any2scsi (cptr [i ].dataptr , isa_page_to_bus (sg_page (sg ))
462
- + sg -> offset );
463
- any2scsi (cptr [i ].datalen , sg -> length );
484
+ any2scsi (acmd -> chain [i ].dataptr , sg_dma_address (sg ));
485
+ any2scsi (acmd -> chain [i ].datalen , sg_dma_len (sg ));
464
486
};
465
487
any2scsi (ccb [mbo ].datalen , sg_count * sizeof (struct chain ));
466
- any2scsi (ccb [mbo ].dataptr , isa_virt_to_bus ( cptr ) );
488
+ any2scsi (ccb [mbo ].dataptr , acmd -> chain_handle );
467
489
#ifdef DEBUG
468
- shost_printk (KERN_DEBUG , sh , "cptr %p: " , cptr );
469
- print_hex_dump_bytes ("cptr: " , DUMP_PREFIX_NONE , cptr , 18 );
490
+ shost_printk (KERN_DEBUG , sh , "cptr %p: " , acmd -> chain );
491
+ print_hex_dump_bytes ("cptr: " , DUMP_PREFIX_NONE , acmd -> chain , 18 );
470
492
#endif
471
493
} else {
472
494
ccb [mbo ].op = 0 ; /* SCSI Initiator Command */
473
- cmd -> host_scribble = NULL ;
474
495
any2scsi (ccb [mbo ].datalen , 0 );
475
496
any2scsi (ccb [mbo ].dataptr , 0 );
476
497
};
@@ -488,24 +509,29 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
488
509
spin_unlock_irqrestore (sh -> host_lock , flags );
489
510
490
511
return 0 ;
512
+ out_free_chain :
513
+ kfree (acmd -> chain );
514
+ acmd -> chain = NULL ;
515
+ out_unmap :
516
+ scsi_dma_unmap (cmd );
517
+ return SCSI_MLQUEUE_HOST_BUSY ;
491
518
}
492
519
493
520
/* Initialize mailboxes */
494
521
static void setup_mailboxes (struct Scsi_Host * sh )
495
522
{
496
523
struct aha1542_hostdata * aha1542 = shost_priv (sh );
497
- int i ;
498
- struct mailbox * mb = aha1542 -> mb ;
499
- struct ccb * ccb = aha1542 -> ccb ;
500
-
501
524
u8 mb_cmd [5 ] = { CMD_MBINIT , AHA1542_MAILBOXES , 0 , 0 , 0 };
525
+ int i ;
502
526
503
527
for (i = 0 ; i < AHA1542_MAILBOXES ; i ++ ) {
504
- mb [i ].status = mb [AHA1542_MAILBOXES + i ].status = 0 ;
505
- any2scsi (mb [i ].ccbptr , isa_virt_to_bus (& ccb [i ]));
528
+ aha1542 -> mb [i ].status = 0 ;
529
+ any2scsi (aha1542 -> mb [i ].ccbptr ,
530
+ aha1542 -> ccb_handle + i * sizeof (struct ccb ));
531
+ aha1542 -> mb [AHA1542_MAILBOXES + i ].status = 0 ;
506
532
};
507
533
aha1542_intr_reset (sh -> io_port ); /* reset interrupts, so they don't block */
508
- any2scsi (( mb_cmd + 2 ), isa_virt_to_bus ( mb ) );
534
+ any2scsi (mb_cmd + 2 , aha1542 -> mb_handle );
509
535
if (aha1542_out (sh -> io_port , mb_cmd , 5 ))
510
536
shost_printk (KERN_ERR , sh , "failed setting up mailboxes\n" );
511
537
aha1542_intr_reset (sh -> io_port );
@@ -739,11 +765,26 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
739
765
if (aha1542 -> bios_translation == BIOS_TRANSLATION_25563 )
740
766
shost_printk (KERN_INFO , sh , "Using extended bios translation\n" );
741
767
768
+ if (dma_set_mask_and_coherent (pdev , DMA_BIT_MASK (24 )) < 0 )
769
+ goto unregister ;
770
+
771
+ aha1542 -> mb = dma_alloc_coherent (pdev ,
772
+ AHA1542_MAILBOXES * 2 * sizeof (struct mailbox ),
773
+ & aha1542 -> mb_handle , GFP_KERNEL );
774
+ if (!aha1542 -> mb )
775
+ goto unregister ;
776
+
777
+ aha1542 -> ccb = dma_alloc_coherent (pdev ,
778
+ AHA1542_MAILBOXES * sizeof (struct ccb ),
779
+ & aha1542 -> ccb_handle , GFP_KERNEL );
780
+ if (!aha1542 -> ccb )
781
+ goto free_mb ;
782
+
742
783
setup_mailboxes (sh );
743
784
744
785
if (request_irq (sh -> irq , aha1542_interrupt , 0 , "aha1542" , sh )) {
745
786
shost_printk (KERN_ERR , sh , "Unable to allocate IRQ.\n" );
746
- goto unregister ;
787
+ goto free_ccb ;
747
788
}
748
789
if (sh -> dma_channel != 0xFF ) {
749
790
if (request_dma (sh -> dma_channel , "aha1542" )) {
@@ -762,11 +803,18 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
762
803
scsi_scan_host (sh );
763
804
764
805
return sh ;
806
+
765
807
free_dma :
766
808
if (sh -> dma_channel != 0xff )
767
809
free_dma (sh -> dma_channel );
768
810
free_irq :
769
811
free_irq (sh -> irq , sh );
812
+ free_ccb :
813
+ dma_free_coherent (pdev , AHA1542_MAILBOXES * sizeof (struct ccb ),
814
+ aha1542 -> ccb , aha1542 -> ccb_handle );
815
+ free_mb :
816
+ dma_free_coherent (pdev , AHA1542_MAILBOXES * 2 * sizeof (struct mailbox ),
817
+ aha1542 -> mb , aha1542 -> mb_handle );
770
818
unregister :
771
819
scsi_host_put (sh );
772
820
release :
@@ -777,9 +825,16 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
777
825
778
826
static int aha1542_release (struct Scsi_Host * sh )
779
827
{
828
+ struct aha1542_hostdata * aha1542 = shost_priv (sh );
829
+ struct device * dev = sh -> dma_dev ;
830
+
780
831
scsi_remove_host (sh );
781
832
if (sh -> dma_channel != 0xff )
782
833
free_dma (sh -> dma_channel );
834
+ dma_free_coherent (dev , AHA1542_MAILBOXES * sizeof (struct ccb ),
835
+ aha1542 -> ccb , aha1542 -> ccb_handle );
836
+ dma_free_coherent (dev , AHA1542_MAILBOXES * 2 * sizeof (struct mailbox ),
837
+ aha1542 -> mb , aha1542 -> mb_handle );
783
838
if (sh -> irq )
784
839
free_irq (sh -> irq , sh );
785
840
if (sh -> io_port && sh -> n_io_port )
@@ -826,7 +881,8 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
826
881
827
882
aha1542 -> aha1542_last_mbo_used = mbo ;
828
883
829
- any2scsi (mb [mbo ].ccbptr , isa_virt_to_bus (& ccb [mbo ])); /* This gets trashed for some reason */
884
+ /* This gets trashed for some reason */
885
+ any2scsi (mb [mbo ].ccbptr , aha1542 -> ccb_handle + mbo * sizeof (* ccb ));
830
886
831
887
memset (& ccb [mbo ], 0 , sizeof (struct ccb ));
832
888
@@ -901,8 +957,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
901
957
*/
902
958
continue ;
903
959
}
904
- kfree (tmp_cmd -> host_scribble );
905
- tmp_cmd -> host_scribble = NULL ;
960
+ aha1542_free_cmd (tmp_cmd );
906
961
aha1542 -> int_cmds [i ] = NULL ;
907
962
aha1542 -> mb [i ].status = 0 ;
908
963
}
@@ -946,6 +1001,7 @@ static struct scsi_host_template driver_template = {
946
1001
.module = THIS_MODULE ,
947
1002
.proc_name = "aha1542" ,
948
1003
.name = "Adaptec 1542" ,
1004
+ .cmd_size = sizeof (struct aha1542_cmd ),
949
1005
.queuecommand = aha1542_queuecommand ,
950
1006
.eh_device_reset_handler = aha1542_dev_reset ,
951
1007
.eh_bus_reset_handler = aha1542_bus_reset ,
0 commit comments