Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libsas.h
Go to the documentation of this file.
1 /*
2  * SAS host prototypes and structures header file
3  *
4  * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5  * Copyright (C) 2005 Luben Tuikov <[email protected]>
6  *
7  * This file is licensed under GPLv2.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  *
24  */
25 
26 #ifndef _LIBSAS_H_
27 #define _LIBSAS_H_
28 
29 
30 #include <linux/timer.h>
31 #include <linux/pci.h>
32 #include <scsi/sas.h>
33 #include <linux/libata.h>
34 #include <linux/list.h>
35 #include <scsi/scsi_device.h>
36 #include <scsi/scsi_cmnd.h>
38 #include <linux/scatterlist.h>
39 #include <linux/slab.h>
40 
41 struct block_device;
42 
43 enum sas_class {
44  SAS,
46 };
47 
52 };
53 
57 };
58 
59 /* The events are mnemonically described in sas_dump.c
60  * so when updating/adding events here, please also
61  * update the other file too.
62  */
63 enum ha_event {
66 };
67 
68 enum port_event {
75 };
76 
77 enum phy_event {
81  PHYE_SPINUP_HOLD = 3, /* hot plug SATA, no COMWAKE sent */
84 };
85 
95 };
96 
97 /* ---------- Expander Devices ---------- */
98 
99 #define to_dom_device(_obj) container_of(_obj, struct domain_device, dev_obj)
100 #define to_dev_attr(_attr) container_of(_attr, struct domain_dev_attribute,\
101  attr)
102 
107 };
108 
114 };
115 
116 struct ex_phy {
117  int phy_id;
118 
120 
123 
127 
130 
133 
136  u8 virtual:1;
137 
139 
140  struct sas_phy *phy;
141  struct sas_port *port;
142 };
143 
146 
150 
154 
156 
157  struct ex_phy *ex_phy;
159 
160  struct mutex cmd_mutex;
161 };
162 
163 /* ---------- SATA device ---------- */
167 };
168 
169 #define ATA_RESP_FIS_SIZE 24
170 
171 struct sata_device {
173  struct smp_resp rps_resp; /* report_phy_sata_resp */
174  u8 port_no; /* port number, if this is a PM (Port) */
176 
177  struct ata_port *ap;
180 };
181 
182 struct ssp_device {
183  struct list_head eh_list_node; /* pending a user requested eh action */
185 };
186 
187 enum {
189  SAS_DEV_FOUND, /* device notified to lldd */
194 };
195 
199 
203 
204  int pathways;
205 
207  struct list_head siblings; /* devices on the same level */
208  struct asd_sas_port *port; /* shortcut to root of the tree */
209  struct sas_phy *phy;
210 
212  struct list_head disco_list_node; /* awaiting probe or destruct */
213 
216 
217  struct sas_rphy *rphy;
218 
221 
223 
224  union {
226  struct sata_device sata_dev; /* STP & directly attached */
228  };
229 
230  void *lldd_dev;
231  unsigned long state;
232  struct kref kref;
233 };
234 
235 struct sas_work {
238 };
239 
240 static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
241 {
242  INIT_WORK(&sw->work, fn);
243  INIT_LIST_HEAD(&sw->drain_node);
244 }
245 
247  struct sas_work work;
249 };
250 
251 static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)
252 {
253  struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work);
254 
255  return ev;
256 }
257 
260  unsigned long pending;
262  u8 eeds_a[8];
263  u8 eeds_b[8];
265 };
266 
267 /* The port struct is Class:RW, driver:RO */
268 struct asd_sas_port {
269 /* private: */
271 
279 
280  struct sas_work work;
282 
283 /* public: */
284  int id;
285 
286  enum sas_class class;
291 
293 
296  int num_phys;
298 
299  struct sas_ha_struct *ha;
300 
301  struct sas_port *port;
302 
303  void *lldd_port; /* not touched by the sas class code */
304 };
305 
307  struct sas_work work;
308  struct asd_sas_phy *phy;
309 };
310 
311 static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work)
312 {
313  struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work);
314 
315  return ev;
316 }
317 
318 /* The phy pretty much is controlled by the LLDD.
319  * The class only reads those fields.
320  */
321 struct asd_sas_phy {
322 /* private: */
325 
326  unsigned long port_events_pending;
327  unsigned long phy_events_pending;
328 
329  int error;
331 
332  struct sas_phy *phy;
333 
334 /* public: */
335  /* The following are class:RO, driver:R/W */
336  int enabled; /* must be set */
337 
338  int id; /* must be set */
339  enum sas_class class;
342 
347 
348  u8 *sas_addr; /* must be set */
349  u8 attached_sas_addr[SAS_ADDR_SIZE]; /* class:RO, driver: R/W */
350 
352  u8 *frame_rcvd; /* must be set */
354 
357 
358  struct list_head port_phy_el; /* driver:RO */
359  struct asd_sas_port *port; /* Class:RW, driver: RO */
360 
361  struct sas_ha_struct *ha; /* may be set; the class sets it anyway */
362 
363  void *lldd_phy; /* not touched by the sas_class_code */
364 };
365 
366 struct scsi_core {
367  struct Scsi_Host *shost;
368 
373 
375 };
376 
377 struct sas_ha_event {
378  struct sas_work work;
379  struct sas_ha_struct *ha;
380 };
381 
382 static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work)
383 {
384  struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work);
385 
386  return ev;
387 }
388 
394 };
395 
397 /* private: */
399  unsigned long pending;
400 
401  struct list_head defer_q; /* work queued while draining */
403  unsigned long state;
408 
410 
411  struct scsi_core core;
412 
413 /* public: */
414  char *sas_ha_name;
415  struct device *dev; /* should be set */
416  struct module *lldd_module; /* should be set */
417 
418  u8 *sas_addr; /* must be set */
420 
422  struct asd_sas_phy **sas_phy; /* array of valid pointers, must be set */
423  struct asd_sas_port **sas_port; /* array of valid pointers, must be set */
424  int num_phys; /* must be set, gt 0, static */
425 
426  /* The class calls this to send a task for execution. */
429  int strict_wide_ports; /* both sas_addr and attached_sas_addr must match
430  * their siblings when forming wide ports */
431 
432  /* LLDD calls these to notify the class of an event. */
436 
437  void *lldd_ha; /* not touched by sas class code */
438 
439  struct list_head eh_done_q; /* complete via scsi_eh_flush_done_q */
440  struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */
441 };
442 
443 #define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
444 
445 static inline struct domain_device *
446 starget_to_domain_dev(struct scsi_target *starget) {
447  return starget->hostdata;
448 }
449 
450 static inline struct domain_device *
451 sdev_to_domain_dev(struct scsi_device *sdev) {
452  return starget_to_domain_dev(sdev->sdev_target);
453 }
454 
455 static inline struct ata_device *sas_to_ata_dev(struct domain_device *dev)
456 {
457  return &dev->sata_dev.ap->link.device[0];
458 }
459 
460 static inline struct domain_device *
461 cmd_to_domain_dev(struct scsi_cmnd *cmd)
462 {
463  return sdev_to_domain_dev(cmd->device);
464 }
465 
466 void sas_hash_addr(u8 *hashed, const u8 *sas_addr);
467 
468 /* Before calling a notify event, LLDD should use this function
469  * when the link is severed (possibly from its tasklet).
470  * The idea is that the Class only reads those, while the LLDD,
471  * can R/W these (thus avoiding a race).
472  */
473 static inline void sas_phy_disconnected(struct asd_sas_phy *phy)
474 {
477 }
478 
479 static inline unsigned int to_sas_gpio_od(int device, int bit)
480 {
481  return 3 * device + bit;
482 }
483 
484 static inline void sas_put_local_phy(struct sas_phy *phy)
485 {
486  put_device(&phy->dev);
487 }
488 
489 #ifdef CONFIG_SCSI_SAS_HOST_SMP
490 int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
491 #else
492 static inline int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count)
493 {
494  return -1;
495 }
496 #endif
497 
498 /* ---------- Tasks ---------- */
499 /*
500  service_response | SAS_TASK_COMPLETE | SAS_TASK_UNDELIVERED |
501  exec_status | | |
502  ---------------------+---------------------+-----------------------+
503  SAM_... | X | |
504  DEV_NO_RESPONSE | X | X |
505  INTERRUPTED | X | |
506  QUEUE_FULL | | X |
507  DEVICE_UNKNOWN | | X |
508  SG_ERR | | X |
509  ---------------------+---------------------+-----------------------+
510  */
511 
515 };
516 
518  /* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
519  * them here to silence 'case value not in enumerated type' warnings
520  */
522 
537 };
538 
539 /* When a task finishes with a response, the LLDD examines the
540  * response:
541  * - For an ATA task task_status_struct::stat is set to
542  * SAS_PROTO_RESPONSE, and the task_status_struct::buf is set to the
543  * contents of struct ata_task_resp.
544  * - For SSP tasks, if no data is present or status/TMF response
545  * is valid, task_status_struct::stat is set. If data is present
546  * (SENSE data), the LLDD copies up to SAS_STATUS_BUF_SIZE, sets
547  * task_status_struct::buf_valid_size, and task_status_struct::stat is
548  * set to SAM_CHECK_COND.
549  *
550  * "buf" has format SCSI Sense for SSP task, or struct ata_task_resp
551  * for ATA task.
552  *
553  * "frame_len" is the total frame length, which could be more or less
554  * than actually copied.
555  *
556  * Tasks ending with response, always set the residual field.
557  */
560  u8 ending_fis[ATA_RESP_FIS_SIZE]; /* dev to host or data-in */
561 };
562 
563 #define SAS_STATUS_BUF_SIZE 96
564 
569 
571 
574 };
575 
576 /* ATA and ATAPI task queuable to a SAS LLDD.
577  */
578 struct sas_ata_task {
580  u8 atapi_packet[16]; /* 0 if not ATAPI task */
581 
582  u8 retry_count; /* hardware retry, should be > 0 */
583 
584  u8 dma_xfer:1; /* PIO:0 or DMA:1 */
588 
590 };
591 
592 struct sas_smp_task {
595 };
596 
602 };
603 
604 struct sas_ssp_task {
605  u8 retry_count; /* hardware retry, should be > 0 */
606 
607  u8 LUN[8];
611  u8 cdb[16];
612 };
613 
614 struct sas_task {
616  struct list_head list;
617 
620 
622 
623  union {
627  };
628 
632  u8 data_dir:2; /* Use PCI_DMA_... */
633 
635  void (*task_done)(struct sas_task *);
636 
637  void *lldd_task; /* for use by LLDDs */
638  void *uldd_task;
640 };
641 
643  /* standard/extra infrastructure for slow path commands (SMP and
644  * internal lldd commands
645  */
648 };
649 
650 #define SAS_TASK_STATE_PENDING 1
651 #define SAS_TASK_STATE_DONE 2
652 #define SAS_TASK_STATE_ABORTED 4
653 #define SAS_TASK_NEED_DEV_RESET 8
654 #define SAS_TASK_AT_INITIATOR 16
655 
656 extern struct sas_task *sas_alloc_task(gfp_t flags);
657 extern struct sas_task *sas_alloc_slow_task(gfp_t flags);
658 extern void sas_free_task(struct sas_task *task);
659 
661  /* The class calls these to notify the LLDD of an event. */
664 
665  /* The class calls these when a device is found or gone. */
668 
669  int (*lldd_execute_task)(struct sas_task *, int num,
670  gfp_t gfp_flags);
671 
672  /* Task Management Functions. Must be called from process context. */
682 
683  /* Port and Adapter management */
686 
687  /* Phy management */
688  int (*lldd_control_phy)(struct asd_sas_phy *, enum phy_func, void *);
689 
690  /* GPIO support */
691  int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
692  u8 reg_index, u8 reg_count, u8 *write_data);
693 };
694 
695 extern int sas_register_ha(struct sas_ha_struct *);
696 extern int sas_unregister_ha(struct sas_ha_struct *);
697 extern void sas_prep_resume_ha(struct sas_ha_struct *sas_ha);
698 extern void sas_resume_ha(struct sas_ha_struct *sas_ha);
699 extern void sas_suspend_ha(struct sas_ha_struct *sas_ha);
700 
701 int sas_set_phy_speed(struct sas_phy *phy,
702  struct sas_phy_linkrates *rates);
703 int sas_phy_reset(struct sas_phy *phy, int hard_reset);
704 int sas_queue_up(struct sas_task *task);
705 extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
706 extern int sas_target_alloc(struct scsi_target *);
707 extern int sas_slave_configure(struct scsi_device *);
708 extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
709  int reason);
710 extern int sas_change_queue_type(struct scsi_device *, int qt);
711 extern int sas_bios_param(struct scsi_device *,
712  struct block_device *,
713  sector_t capacity, int *hsc);
714 extern struct scsi_transport_template *
717 
719 
720 void sas_init_ex_attr(void);
721 
723 
724 void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
725 void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
726 int sas_discover_event(struct asd_sas_port *, enum discover_event ev);
727 
728 int sas_discover_sata(struct domain_device *);
729 int sas_discover_end_dev(struct domain_device *);
730 
731 void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
732 
733 void sas_init_dev(struct domain_device *);
734 
735 void sas_task_abort(struct sas_task *);
736 int sas_eh_abort_handler(struct scsi_cmnd *cmd);
739 
740 extern void sas_target_destroy(struct scsi_target *);
741 extern int sas_slave_alloc(struct scsi_device *);
742 extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
743 extern int sas_drain_work(struct sas_ha_struct *ha);
744 
745 extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
746  struct request *req);
747 
748 extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
749  struct ssp_response_iu *iu);
750 struct sas_phy *sas_get_local_phy(struct domain_device *dev);
751 
752 int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
753 
754 #endif /* _SASLIB_H_ */