0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 #ifndef _AIC7XXX_LINUX_H_
0060 #define _AIC7XXX_LINUX_H_
0061
0062 #include <linux/types.h>
0063 #include <linux/blkdev.h>
0064 #include <linux/delay.h>
0065 #include <linux/ioport.h>
0066 #include <linux/pci.h>
0067 #include <linux/interrupt.h>
0068 #include <linux/module.h>
0069 #include <linux/slab.h>
0070 #include <asm/byteorder.h>
0071 #include <asm/io.h>
0072
0073 #include <scsi/scsi.h>
0074 #include <scsi/scsi_cmnd.h>
0075 #include <scsi/scsi_eh.h>
0076 #include <scsi/scsi_device.h>
0077 #include <scsi/scsi_host.h>
0078 #include <scsi/scsi_tcq.h>
0079 #include <scsi/scsi_transport.h>
0080 #include <scsi/scsi_transport_spi.h>
0081
0082
0083 #define AIC_LIB_PREFIX ahc
0084
0085 #include "cam.h"
0086 #include "queue.h"
0087 #include "scsi_message.h"
0088 #include "aiclib.h"
0089
0090
0091 #ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
0092 #ifdef CONFIG_AIC7XXX_DEBUG_MASK
0093 #define AHC_DEBUG 1
0094 #define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK
0095 #else
0096
0097
0098
0099 #define AHC_DEBUG 1
0100 #endif
0101
0102 #endif
0103
0104
0105 struct ahc_softc;
0106 typedef struct pci_dev *ahc_dev_softc_t;
0107 typedef struct scsi_cmnd *ahc_io_ctx_t;
0108
0109
0110 #define ahc_htobe16(x) cpu_to_be16(x)
0111 #define ahc_htobe32(x) cpu_to_be32(x)
0112 #define ahc_htobe64(x) cpu_to_be64(x)
0113 #define ahc_htole16(x) cpu_to_le16(x)
0114 #define ahc_htole32(x) cpu_to_le32(x)
0115 #define ahc_htole64(x) cpu_to_le64(x)
0116
0117 #define ahc_be16toh(x) be16_to_cpu(x)
0118 #define ahc_be32toh(x) be32_to_cpu(x)
0119 #define ahc_be64toh(x) be64_to_cpu(x)
0120 #define ahc_le16toh(x) le16_to_cpu(x)
0121 #define ahc_le32toh(x) le32_to_cpu(x)
0122 #define ahc_le64toh(x) le64_to_cpu(x)
0123
0124
0125 extern u_int aic7xxx_no_probe;
0126 extern u_int aic7xxx_allow_memio;
0127 extern struct scsi_host_template aic7xxx_driver_template;
0128
0129
0130
0131 typedef uint32_t bus_size_t;
0132
0133 typedef enum {
0134 BUS_SPACE_MEMIO,
0135 BUS_SPACE_PIO
0136 } bus_space_tag_t;
0137
0138 typedef union {
0139 u_long ioport;
0140 volatile uint8_t __iomem *maddr;
0141 } bus_space_handle_t;
0142
0143 typedef struct bus_dma_segment
0144 {
0145 dma_addr_t ds_addr;
0146 bus_size_t ds_len;
0147 } bus_dma_segment_t;
0148
0149 struct ahc_linux_dma_tag
0150 {
0151 bus_size_t alignment;
0152 bus_size_t boundary;
0153 bus_size_t maxsize;
0154 };
0155 typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
0156
0157 typedef dma_addr_t bus_dmamap_t;
0158
0159 typedef int bus_dma_filter_t(void*, dma_addr_t);
0160 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
0161
0162 #define BUS_DMA_WAITOK 0x0
0163 #define BUS_DMA_NOWAIT 0x1
0164 #define BUS_DMA_ALLOCNOW 0x2
0165 #define BUS_DMA_LOAD_SEGS 0x4
0166
0167
0168
0169
0170 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
0171 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
0172 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
0173
0174 int ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t ,
0175 bus_size_t , bus_size_t ,
0176 dma_addr_t , dma_addr_t ,
0177 bus_dma_filter_t*, void *,
0178 bus_size_t , int ,
0179 bus_size_t , int ,
0180 bus_dma_tag_t *);
0181
0182 void ahc_dma_tag_destroy(struct ahc_softc *, bus_dma_tag_t );
0183
0184 int ahc_dmamem_alloc(struct ahc_softc *, bus_dma_tag_t ,
0185 void** , int ,
0186 bus_dmamap_t* );
0187
0188 void ahc_dmamem_free(struct ahc_softc *, bus_dma_tag_t ,
0189 void* , bus_dmamap_t );
0190
0191 void ahc_dmamap_destroy(struct ahc_softc *, bus_dma_tag_t ,
0192 bus_dmamap_t );
0193
0194 int ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t ,
0195 bus_dmamap_t , void * ,
0196 bus_size_t , bus_dmamap_callback_t *,
0197 void *, int );
0198
0199 int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
0200
0201
0202
0203
0204 #define BUS_DMASYNC_PREREAD 0x01
0205 #define BUS_DMASYNC_POSTREAD 0x02
0206 #define BUS_DMASYNC_PREWRITE 0x04
0207 #define BUS_DMASYNC_POSTWRITE 0x08
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 #define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
0218
0219
0220 #ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
0221 #define AIC_DEBUG_REGISTERS 1
0222 #else
0223 #define AIC_DEBUG_REGISTERS 0
0224 #endif
0225 #include "aic7xxx.h"
0226
0227
0228 static inline void
0229 ahc_scb_timer_reset(struct scb *scb, u_int usec)
0230 {
0231 }
0232
0233
0234 #include <linux/spinlock.h>
0235
0236 #define AIC7XXX_DRIVER_VERSION "7.0"
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 typedef enum {
0247 AHC_DEV_FREEZE_TIL_EMPTY = 0x02,
0248 AHC_DEV_Q_BASIC = 0x10,
0249 AHC_DEV_Q_TAGGED = 0x20,
0250 AHC_DEV_PERIODIC_OTAG = 0x40,
0251 } ahc_linux_dev_flags;
0252
0253 struct ahc_linux_device {
0254
0255
0256
0257
0258 int active;
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 int openings;
0269
0270
0271
0272
0273
0274 u_int qfrozen;
0275
0276
0277
0278
0279 u_long commands_issued;
0280
0281
0282
0283
0284
0285
0286
0287 u_int tag_success_count;
0288 #define AHC_TAG_SUCCESS_INTERVAL 50
0289
0290 ahc_linux_dev_flags flags;
0291
0292
0293
0294
0295 u_int maxtags;
0296
0297
0298
0299
0300
0301 u_int tags_on_last_queuefull;
0302
0303
0304
0305
0306
0307
0308
0309 u_int last_queuefull_same_count;
0310 #define AHC_LOCK_TAGS_COUNT 50
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 u_int commands_since_idle_or_otag;
0322 #define AHC_OTAG_THRESH 500
0323 };
0324
0325
0326
0327
0328
0329
0330
0331
0332 #define AHC_NSEG 128
0333
0334
0335
0336
0337 struct scb_platform_data {
0338 struct ahc_linux_device *dev;
0339 dma_addr_t buf_busaddr;
0340 uint32_t xfer_len;
0341 uint32_t sense_resid;
0342 };
0343
0344
0345
0346
0347
0348
0349
0350 struct ahc_platform_data {
0351
0352
0353
0354 struct scsi_target *starget[AHC_NUM_TARGETS];
0355
0356 spinlock_t spin_lock;
0357 u_int qfrozen;
0358 struct completion *eh_done;
0359 struct Scsi_Host *host;
0360 #define AHC_LINUX_NOIRQ ((uint32_t)~0)
0361 uint32_t irq;
0362 uint32_t bios_address;
0363 resource_size_t mem_busaddr;
0364 };
0365
0366 void ahc_delay(long);
0367
0368
0369
0370 uint8_t ahc_inb(struct ahc_softc * ahc, long port);
0371 void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
0372 void ahc_outsb(struct ahc_softc * ahc, long port,
0373 uint8_t *, int count);
0374 void ahc_insb(struct ahc_softc * ahc, long port,
0375 uint8_t *, int count);
0376
0377
0378 int ahc_linux_register_host(struct ahc_softc *,
0379 struct scsi_host_template *);
0380
0381
0382
0383
0384 static inline void
0385 ahc_lockinit(struct ahc_softc *ahc)
0386 {
0387 spin_lock_init(&ahc->platform_data->spin_lock);
0388 }
0389
0390 static inline void
0391 ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
0392 {
0393 spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
0394 }
0395
0396 static inline void
0397 ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
0398 {
0399 spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 #define PCIR_DEVVENDOR 0x00
0413 #define PCIR_VENDOR 0x00
0414 #define PCIR_DEVICE 0x02
0415 #define PCIR_COMMAND 0x04
0416 #define PCIM_CMD_PORTEN 0x0001
0417 #define PCIM_CMD_MEMEN 0x0002
0418 #define PCIM_CMD_BUSMASTEREN 0x0004
0419 #define PCIM_CMD_MWRICEN 0x0010
0420 #define PCIM_CMD_PERRESPEN 0x0040
0421 #define PCIM_CMD_SERRESPEN 0x0100
0422 #define PCIR_STATUS 0x06
0423 #define PCIR_REVID 0x08
0424 #define PCIR_PROGIF 0x09
0425 #define PCIR_SUBCLASS 0x0a
0426 #define PCIR_CLASS 0x0b
0427 #define PCIR_CACHELNSZ 0x0c
0428 #define PCIR_LATTIMER 0x0d
0429 #define PCIR_HEADERTYPE 0x0e
0430 #define PCIM_MFDEV 0x80
0431 #define PCIR_BIST 0x0f
0432 #define PCIR_CAP_PTR 0x34
0433
0434
0435 #define PCIR_MAPS 0x10
0436
0437 typedef enum
0438 {
0439 AHC_POWER_STATE_D0,
0440 AHC_POWER_STATE_D1,
0441 AHC_POWER_STATE_D2,
0442 AHC_POWER_STATE_D3
0443 } ahc_power_state;
0444
0445
0446 #ifdef CONFIG_EISA
0447 int ahc_linux_eisa_init(void);
0448 void ahc_linux_eisa_exit(void);
0449 int aic7770_map_registers(struct ahc_softc *ahc,
0450 u_int port);
0451 int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
0452 #else
0453 static inline int ahc_linux_eisa_init(void) {
0454 return -ENODEV;
0455 }
0456 static inline void ahc_linux_eisa_exit(void) {
0457 }
0458 #endif
0459
0460
0461 #ifdef CONFIG_PCI
0462 int ahc_linux_pci_init(void);
0463 void ahc_linux_pci_exit(void);
0464 int ahc_pci_map_registers(struct ahc_softc *ahc);
0465 int ahc_pci_map_int(struct ahc_softc *ahc);
0466
0467 uint32_t ahc_pci_read_config(ahc_dev_softc_t pci,
0468 int reg, int width);
0469
0470 void ahc_pci_write_config(ahc_dev_softc_t pci,
0471 int reg, uint32_t value,
0472 int width);
0473
0474 static inline int ahc_get_pci_function(ahc_dev_softc_t);
0475 static inline int
0476 ahc_get_pci_function(ahc_dev_softc_t pci)
0477 {
0478 return (PCI_FUNC(pci->devfn));
0479 }
0480
0481 static inline int ahc_get_pci_slot(ahc_dev_softc_t);
0482 static inline int
0483 ahc_get_pci_slot(ahc_dev_softc_t pci)
0484 {
0485 return (PCI_SLOT(pci->devfn));
0486 }
0487
0488 static inline int ahc_get_pci_bus(ahc_dev_softc_t);
0489 static inline int
0490 ahc_get_pci_bus(ahc_dev_softc_t pci)
0491 {
0492 return (pci->bus->number);
0493 }
0494 #else
0495 static inline int ahc_linux_pci_init(void) {
0496 return 0;
0497 }
0498 static inline void ahc_linux_pci_exit(void) {
0499 }
0500 #endif
0501
0502 static inline void ahc_flush_device_writes(struct ahc_softc *);
0503 static inline void
0504 ahc_flush_device_writes(struct ahc_softc *ahc)
0505 {
0506
0507 ahc_inb(ahc, INTSTAT);
0508 }
0509
0510
0511 int ahc_proc_write_seeprom(struct Scsi_Host *, char *, int);
0512 int ahc_linux_show_info(struct seq_file *, struct Scsi_Host *);
0513
0514
0515
0516
0517 static inline
0518 void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
0519 {
0520 cmd->result &= ~(CAM_STATUS_MASK << 16);
0521 cmd->result |= status << 16;
0522 }
0523
0524 static inline
0525 void ahc_set_transaction_status(struct scb *scb, uint32_t status)
0526 {
0527 ahc_cmd_set_transaction_status(scb->io_ctx,status);
0528 }
0529
0530 static inline
0531 void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
0532 {
0533 cmd->result &= ~0xFFFF;
0534 cmd->result |= status;
0535 }
0536
0537 static inline
0538 void ahc_set_scsi_status(struct scb *scb, uint32_t status)
0539 {
0540 ahc_cmd_set_scsi_status(scb->io_ctx, status);
0541 }
0542
0543 static inline
0544 uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
0545 {
0546 return ((cmd->result >> 16) & CAM_STATUS_MASK);
0547 }
0548
0549 static inline
0550 uint32_t ahc_get_transaction_status(struct scb *scb)
0551 {
0552 return (ahc_cmd_get_transaction_status(scb->io_ctx));
0553 }
0554
0555 static inline
0556 uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
0557 {
0558 return (cmd->result & 0xFFFF);
0559 }
0560
0561 static inline
0562 uint32_t ahc_get_scsi_status(struct scb *scb)
0563 {
0564 return (ahc_cmd_get_scsi_status(scb->io_ctx));
0565 }
0566
0567 static inline
0568 void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
0569 {
0570
0571
0572
0573
0574 }
0575
0576 static inline
0577 u_long ahc_get_transfer_length(struct scb *scb)
0578 {
0579 return (scb->platform_data->xfer_len);
0580 }
0581
0582 static inline
0583 int ahc_get_transfer_dir(struct scb *scb)
0584 {
0585 return (scb->io_ctx->sc_data_direction);
0586 }
0587
0588 static inline
0589 void ahc_set_residual(struct scb *scb, u_long resid)
0590 {
0591 scsi_set_resid(scb->io_ctx, resid);
0592 }
0593
0594 static inline
0595 void ahc_set_sense_residual(struct scb *scb, u_long resid)
0596 {
0597 scb->platform_data->sense_resid = resid;
0598 }
0599
0600 static inline
0601 u_long ahc_get_residual(struct scb *scb)
0602 {
0603 return scsi_get_resid(scb->io_ctx);
0604 }
0605
0606 static inline
0607 u_long ahc_get_sense_residual(struct scb *scb)
0608 {
0609 return (scb->platform_data->sense_resid);
0610 }
0611
0612 static inline
0613 int ahc_perform_autosense(struct scb *scb)
0614 {
0615
0616
0617
0618
0619
0620 return (1);
0621 }
0622
0623 static inline uint32_t
0624 ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
0625 {
0626 return (sizeof(struct scsi_sense_data));
0627 }
0628
0629 static inline void
0630 ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
0631 struct ahc_devinfo *devinfo)
0632 {
0633
0634 }
0635
0636 static inline void
0637 ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
0638 {
0639 }
0640
0641 int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
0642 void ahc_platform_free(struct ahc_softc *ahc);
0643 void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
0644
0645 static inline void
0646 ahc_freeze_scb(struct scb *scb)
0647 {
0648 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
0649 scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
0650 scb->platform_data->dev->qfrozen++;
0651 }
0652 }
0653
0654 void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
0655 struct ahc_devinfo *devinfo, ahc_queue_alg);
0656 int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
0657 char channel, int lun, u_int tag,
0658 role_t role, uint32_t status);
0659 irqreturn_t
0660 ahc_linux_isr(int irq, void *dev_id);
0661 void ahc_platform_flushwork(struct ahc_softc *ahc);
0662 void ahc_done(struct ahc_softc*, struct scb*);
0663 void ahc_send_async(struct ahc_softc *, char channel,
0664 u_int target, u_int lun, ac_code);
0665 void ahc_print_path(struct ahc_softc *, struct scb *);
0666
0667 #ifdef CONFIG_PCI
0668 #define AHC_PCI_CONFIG 1
0669 #else
0670 #define AHC_PCI_CONFIG 0
0671 #endif
0672 #define bootverbose aic7xxx_verbose
0673 extern u_int aic7xxx_verbose;
0674 #endif